/** fmDeletePolicer * \ingroup policer * * \chips FM3000, FM4000, FM6000, FM10000 * * \desc Delete a policer previously created with a call to * fmCreatePolicer. * * \param[in] sw is the switch on which to operate. * * \param[in] policer is the policer number to delete. * * \return FM_OK if successful. * \return FM_ERR_INVALID_SWITCH if sw is invalid. * \return FM_ERR_INVALID_POLICER if the specified policer number * does not exist in the specified bank. * \return FM_ERR_INVALID_ARGUMENT if policer value is out of range. * *****************************************************************************/ fm_status fmDeletePolicer(fm_int sw, fm_int policer) { fm_policerInfo *info; fm_switch * switchPtr; FM_API_PREAMBLE("sw = %d, policer = %d\n", sw, policer); FM_API_REQUIRE(POLICER_VALID(policer), FM_ERR_INVALID_ARGUMENT); switchPtr = GET_SWITCH_PTR(sw); info = &switchPtr->policerInfo; err = fmTreeRemove(&info->policers, policer, fmFree); if (err == FM_ERR_NOT_FOUND) { err = FM_ERR_INVALID_POLICER; } if ( (err == FM_OK) && (switchPtr->DeletePolicer != NULL) ) { /* for SWAG */ err = switchPtr->DeletePolicer(sw, policer); } FM_API_POSTAMBLE; } /* end fmDeletePolicer */
/** fm10000MoveReplicationGroupMcastGroup * \ingroup intMulticast * * \desc Move the mcast group to a given replication group. * * \param[in] sw is the switch number. * * \param[in] groupHandle is the new replication group handle. * * \param[in] mcastGroup is the mcast group number. * * \return FM_OK if successful. * \return FM_ERR_INVALID_MULTICAST_GROUP if the replication group * is invalid. * \return FM_ERR_INVALID_PORT if a listener port is invalid * *****************************************************************************/ fm_status fm10000MoveReplicationGroupMcastGroup(fm_int sw, fm_int groupHandle, fm_int mcastGroup) { fm_status err=FM_OK; fm_switch * switchPtr; fm_intReplicationGroup *repliGroup; fm_intReplicationGroup *prevGroup; fm_intMulticastGroup * mcastGroupPtr; fm_intMulticastGroup * mcastGroupTmp; fm10000_MulticastGroup *mcastGroupExt; fm_int groupDestIndex; fm_int newGroupId=FM_MCASTGROUP_REPLICATION_GROUP_DISABLE; fm_int mtableDestIndex; fm_int privateGroup=FALSE; fm_bool removeFromPreviousTree=FALSE; fm_treeIterator iter; fm_uint64 key; fm_intMulticastEcmp * ecmpGroup; FM_LOG_ENTRY( FM_LOG_CAT_MULTICAST, "sw=%d newrepliGroup=%d mcastGroup=%d\n", sw, groupHandle, mcastGroup); switchPtr = GET_SWITCH_PTR(sw); mcastGroupPtr = fmFindMcastGroup(sw, mcastGroup); if ( mcastGroupPtr == NULL ) { err = FM_ERR_INVALID_MULTICAST_GROUP; FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_MULTICAST, err); } mcastGroupExt = mcastGroupPtr->extension; groupDestIndex = -1; /* If the given new replication group is -1, i.e. disable, then we * need to allocate a private replication group for this mcast group * if the latter is active */ if ( groupHandle == FM_MCASTGROUP_REPLICATION_GROUP_DISABLE ) { if (mcastGroupPtr->activated) { privateGroup = TRUE; err = fmCreateReplicationGroupInt(sw, &newGroupId, mcastGroupPtr->logicalPort, &mtableDestIndex, TRUE); FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_MULTICAST, err); FM_LOG_DEBUG(FM_LOG_CAT_MULTICAST, "newRepliGroup %d DestIndex=%d\n", newGroupId, mtableDestIndex); } } else { privateGroup = FALSE; newGroupId = groupHandle; } if (newGroupId != FM_MCASTGROUP_REPLICATION_GROUP_DISABLE) { /* We have to move the mcast group to a new replication group */ repliGroup = findReplicationGroup(sw, newGroupId); if (repliGroup == NULL) { err = FM_ERR_INVALID_MULTICAST_GROUP; FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_MULTICAST, err); } /* Search the tree of mcast groups for a matching entry. */ err = fmTreeFind( &repliGroup->mcastGroupList, (fm_uint64) mcastGroup, (void **) &mcastGroupTmp ); if (err == FM_OK) { /* Error if already in group */ err = FM_ERR_ALREADY_EXISTS; FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_MULTICAST, err); } groupDestIndex = repliGroup->hwDestIndex; if (mcastGroupPtr->activated) { /* This mcast group is active; move all its listeners to the * new replication group. */ /* Update the multicast index attribute for this mcast group */ err = switchPtr->SetLogicalPortAttribute(sw, mcastGroupPtr->logicalPort, FM_LPORT_MULTICAST_INDEX, &groupDestIndex); FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_MULTICAST, err); if (!mcastGroupPtr->readOnlyRepliGroup) { err = MoveListenersToReplicationGroup(sw, newGroupId, mcastGroupPtr); FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_MULTICAST, err); } /* Update the NextHop entry to use the new replicate group. */ mcastGroupExt->mtableDestIndex = groupDestIndex; err = fm10000UpdateNextHopMulticast(sw, mcastGroupPtr->ecmpGroup); FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_MULTICAST, err); fmTreeIterInit(&iter, &mcastGroupPtr->ecmpTree); while (1) { err = fmTreeIterNext(&iter, &key, (void **) &ecmpGroup); if (err != FM_OK) { if (err == FM_ERR_NO_MORE) { err = FM_OK; } break; } err = fm10000UpdateNextHopMulticast(sw, ecmpGroup->ecmpId); FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_MULTICAST, err); } FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_MULTICAST, err); /* Remove the mcastgroup's listeners from previous replication group */ if (!mcastGroupPtr->readOnlyRepliGroup) { err = RemoveListenersFromReplicationGroup(sw, mcastGroupPtr->repliGroup, mcastGroupPtr); FM_LOG_ABORT_ON_ERR ( FM_LOG_CAT_MULTICAST, err ); } /* Release the previous replication group if it was a private one */ if (mcastGroupPtr->privateGroup) { /* No need to remove it from previous group Tree since * the group will be deleted or freed */ removeFromPreviousTree = FALSE; err = fmDeleteReplicationGroupInt(sw, mcastGroupPtr->repliGroup, TRUE); FM_LOG_ABORT_ON_ERR ( FM_LOG_CAT_MULTICAST, err ); } else { /* Remove mcast group from the list of the previous * replication group */ removeFromPreviousTree = TRUE; } } else if (mcastGroupPtr->repliGroup != FM_MCASTGROUP_REPLICATION_GROUP_DISABLE) { /* Remove mcast group from the list of the previous * replication group */ removeFromPreviousTree = TRUE; } /* Insert the mcast group in the list of the new replication group */ err = fmTreeInsert(&repliGroup->mcastGroupList, (fm_uint64) mcastGroup, (void *) mcastGroupPtr); FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_MULTICAST, err); } else if (mcastGroupPtr->repliGroup != FM_MCASTGROUP_REPLICATION_GROUP_DISABLE) { /* Removing a none active mcast group from its replication group */ privateGroup = FALSE; groupDestIndex = -1; removeFromPreviousTree = TRUE; } if (removeFromPreviousTree) { /* Remove mcast group from the list of the previous replication group */ prevGroup = findReplicationGroup(sw, mcastGroupPtr->repliGroup); if (prevGroup == NULL) { err = FM_ERR_INVALID_MULTICAST_GROUP; FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_MULTICAST, err); } err = fmTreeRemove(&prevGroup->mcastGroupList, (fm_uint64) mcastGroup, NULL ); FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_MULTICAST, err); FM_LOG_DEBUG(FM_LOG_CAT_MULTICAST, "mcast group %d deleted from Replication group %d\n", mcastGroup, prevGroup->handle); } /* Update mcast group with info from the new replication group */ mcastGroupPtr->repliGroup = newGroupId; mcastGroupPtr->privateGroup = privateGroup; mcastGroupExt->mtableDestIndex = groupDestIndex; FM_LOG_DEBUG(FM_LOG_CAT_MULTICAST, "mcastgroup %d moved to Replication group %d, index %d\n", mcastGroup, mcastGroupPtr->repliGroup, groupDestIndex); ABORT: FM_LOG_EXIT(FM_LOG_CAT_MULTICAST, err); } /* end fm10000MoveReplicationGroupMcastGroup */