blob: df6844e37b6a0d9fd395236fa6684d21aaa9726f [file] [log] [blame]
/*
* Copyright 2017-present Open Networking Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.drivers.microsemi;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.slf4j.LoggerFactory.getLogger;
import java.time.Duration;
import java.util.Collection;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onlab.util.HexString;
import org.onosproject.drivers.microsemi.yang.MseaCfmNetconfService;
import org.onosproject.drivers.microsemi.yang.utils.MaNameUtil;
import org.onosproject.incubator.net.l2monitoring.cfm.Component;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMepEntry;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMepLbEntry;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultRemoteMepEntry;
import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceAssociation;
import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceDomain;
import org.onosproject.incubator.net.l2monitoring.cfm.Mep;
import org.onosproject.incubator.net.l2monitoring.cfm.Mep.MepDirection;
import org.onosproject.incubator.net.l2monitoring.cfm.Mep.Priority;
import org.onosproject.incubator.net.l2monitoring.cfm.MepEntry;
import org.onosproject.incubator.net.l2monitoring.cfm.MepLbCreate;
import org.onosproject.incubator.net.l2monitoring.cfm.MepLbEntry.MepLbEntryBuilder;
import org.onosproject.incubator.net.l2monitoring.cfm.MepLtCreate;
import org.onosproject.incubator.net.l2monitoring.cfm.RemoteMepEntry;
import org.onosproject.incubator.net.l2monitoring.cfm.RemoteMepEntry.InterfaceStatusTlvType;
import org.onosproject.incubator.net.l2monitoring.cfm.RemoteMepEntry.PortStatusTlvType;
import org.onosproject.incubator.net.l2monitoring.cfm.RemoteMepEntry.RemoteMepEntryBuilder;
import org.onosproject.incubator.net.l2monitoring.cfm.RemoteMepEntry.RemoteMepState;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdShort;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdId;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdDomainName;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdMacUint;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdNone;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepId;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmConfigException;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMdService;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMepProgrammable;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
import org.onosproject.net.driver.AbstractHandlerBehaviour;
import org.onosproject.netconf.DatastoreId;
import org.onosproject.netconf.NetconfController;
import org.onosproject.netconf.NetconfException;
import org.onosproject.netconf.NetconfSession;
import org.onosproject.yang.gen.v1.ietfinettypes.rev20130715.ietfinettypes.DomainName;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.MseaCfm;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.MseaCfmOpParam;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.DefaultMefCfm;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.MefCfm;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.abortloopback.AbortLoopbackInput;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.abortloopback.DefaultAbortLoopbackInput;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.faultalarmdefectbitstype.Bits;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.DefaultMaintenanceDomain;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.DefaultMaintenanceAssociation;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.MdNameAndTypeCombo;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.CcmIntervalEnum;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.ComponentList;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.DefaultComponentList;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.DefaultMaintenanceAssociationEndPoint;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.MaNameAndTypeCombo;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.MaintenanceAssociationEndPoint;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.componentlist.TagTypeEnum;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.maintenanceassociationendpoint.ContinuityCheck;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.maintenanceassociationendpoint.DefaultContinuityCheck;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.maintenanceassociation.maintenanceassociationendpoint.InterfaceEnum;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.mdnameandtypecombo.DefaultMacAddressAndUint;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.mdnameandtypecombo.DefaultNameCharacterString;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.mdnameandtypecombo.DefaultNameDomainName;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.mdnameandtypecombo.DefaultNameNone;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.mdnameandtypecombo.namedomainname.NameDomainNameUnion;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.remotemepstatetype.RemoteMepStateTypeEnum;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.targetaddressgroup.addresstype.DefaultMacAddress;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.targetaddressgroup.addresstype.DefaultMepId;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.transmitloopback.DefaultTransmitLoopbackInput;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.transmitloopback.TransmitLoopbackInput;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.transmitloopback.transmitloopbackinput.DefaultTargetAddress;
import org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.transmitloopback.transmitloopbackinput.TargetAddress;
import org.onosproject.yang.gen.v1.mseasoamfm.rev20160229.mseasoamfm.mefcfm.maintenancedomain.maintenanceassociation.maintenanceassociationendpoint.AugmentedMseaCfmMaintenanceAssociationEndPoint;
import org.onosproject.yang.gen.v1.mseasoamfm.rev20160229.mseasoamfm.mefcfm.maintenancedomain.maintenanceassociation.maintenanceassociationendpoint.DefaultAugmentedMseaCfmMaintenanceAssociationEndPoint;
import org.onosproject.yang.gen.v1.mseatypes.rev20160229.mseatypes.Identifier45;
import org.onosproject.yang.gen.v1.mseatypes.rev20160229.mseatypes.MacAddressAndUintStr;
import org.onosproject.yang.gen.v1.mseatypes.rev20160229.mseatypes.MdLevelType;
import org.onosproject.yang.gen.v1.mseatypes.rev20160229.mseatypes.MepIdType;
import org.onosproject.yang.gen.v1.mseatypes.rev20160229.mseatypes.PriorityType;
import org.onosproject.yang.gen.v1.mseatypes.rev20160229.mseatypes.VlanIdType;
import org.slf4j.Logger;
/**
* Implementation of CfmMepProgrammable for Microsemi EA1000.
*/
public class EA1000CfmMepProgrammable extends AbstractHandlerBehaviour
implements CfmMepProgrammable {
private static final int NUMERIC_ID_MAX = 64;
private static final int REMOTEMEPLIST_MIN_COUNT = 2;
private static final int REMOTEMEPLIST_MAX_COUNT = 9;
private static final int COMPONENT_LIST_SIZE = 1;
private static final int VIDLIST_SIZE_MIN = 1;
private static final int MEP_PORT_MIN = 0;
private static final int MEP_PORT_MAX = 1;
private final Logger log = getLogger(getClass());
public EA1000CfmMepProgrammable() {
log.debug("Loaded handler behaviour EA1000CfmMepProgrammable");
}
@Override
public boolean createMep(MdId mdName, MaIdShort maName, Mep mep)
throws CfmConfigException {
NetconfController controller = checkNotNull(handler().get(NetconfController.class));
NetconfSession session = controller.getDevicesMap()
.get(handler().data().deviceId()).getSession();
MseaCfmNetconfService mseaCfmService =
checkNotNull(handler().get(MseaCfmNetconfService.class));
MaintenanceAssociationEndPoint yangMep = buildYangMepFromApiMep(mep);
CfmMdService cfmMdService = checkNotNull(handler().get(CfmMdService.class));
MaintenanceDomain md = cfmMdService.getMaintenanceDomain(mdName).get();
MaintenanceAssociation ma = cfmMdService.getMaintenanceAssociation(mdName, maName).get();
if (!ma.remoteMepIdList().contains(mep.mepId())) {
throw new CfmConfigException("Mep Id " + mep.mepId() +
" is not present in the remote Mep list for MA " + ma.maId() +
". This is required for EA1000.");
} else if (md.mdNumericId() <= 0 || md.mdNumericId() > NUMERIC_ID_MAX) {
throw new CfmConfigException("Numeric id of MD " + mdName + " must"
+ " be between 1 and 64 inclusive for EA1000");
} else if (ma.maNumericId() <= 0 || ma.maNumericId() > NUMERIC_ID_MAX) {
throw new CfmConfigException("Numeric id of MA " + maName + " must"
+ " be between 1 and 64 inclusive for EA1000");
}
org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain
.MaintenanceAssociation yangMa = buildYangMaFromApiMa(ma);
yangMa.addToMaintenanceAssociationEndPoint(yangMep);
org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm
.mefcfm.MaintenanceDomain yangMd = buildYangMdFromApiMd(md);
yangMd.addToMaintenanceAssociation(yangMa);
MefCfm mefCfm = new DefaultMefCfm();
mefCfm.addToMaintenanceDomain(yangMd);
MseaCfmOpParam mseaCfmOpParam = new MseaCfmOpParam();
mseaCfmOpParam.mefCfm(mefCfm);
try {
mseaCfmService.setMseaCfm(mseaCfmOpParam, session, DatastoreId.RUNNING);
log.info("Created MEP {} on device {}", mdName + "/" + maName +
"/" + mep.mepId(), handler().data().deviceId());
return true;
} catch (NetconfException e) {
log.error("Unable to create MEP {}/{}/{} on device {}",
mdName, maName, mep.mepId(), handler().data().deviceId());
throw new CfmConfigException("Unable to create MEP :" + e.getMessage());
}
}
@Override
public Collection<MepEntry> getAllMeps(MdId mdName, MaIdShort maName) throws CfmConfigException {
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public MepEntry getMep(MdId mdName, MaIdShort maName, MepId mepId)
throws CfmConfigException {
NetconfController controller = checkNotNull(handler().get(NetconfController.class));
if (handler().data().deviceId() == null) {
throw new CfmConfigException("Device is not ready - connecting or "
+ "disconnected for MEP " + mdName + "/" + maName + "/" + mepId);
}
NetconfSession session = controller.getDevicesMap().get(handler().data().deviceId()).getSession();
MseaCfmNetconfService mseaCfmService = checkNotNull(handler().get(MseaCfmNetconfService.class));
try {
MseaCfm mseacfm =
mseaCfmService.getMepFull(mdName, maName, mepId, session);
for (org.onosproject.yang.gen.v1.mseacfm.rev20160229.
mseacfm.mefcfm.MaintenanceDomain replyMd:mseacfm.mefCfm().maintenanceDomain()) {
for (org.onosproject.yang.gen.v1.mseacfm.rev20160229.
mseacfm.mefcfm.maintenancedomain.
MaintenanceAssociation replyMa:replyMd.maintenanceAssociation()) {
for (MaintenanceAssociationEndPoint replyMep:replyMa.maintenanceAssociationEndPoint()) {
return buildApiMepEntryFromYangMep(replyMep, handler().data().deviceId(), mdName, maName);
}
}
}
log.warn("Mep " + mepId + " not found on device " + handler().data().deviceId());
return null;
} catch (NetconfException e) {
log.error("Unable to get MEP {}/{}/{} on device {}",
mdName, maName, mepId, handler().data().deviceId());
throw new CfmConfigException("Unable to create MEP :" + e.getMessage());
}
}
@Override
public boolean deleteMep(MdId mdName, MaIdShort maName, MepId mepId) throws CfmConfigException {
NetconfController controller = checkNotNull(handler().get(NetconfController.class));
NetconfSession session = controller.getDevicesMap().get(handler().data().deviceId()).getSession();
MseaCfmNetconfService mseaCfmService = checkNotNull(handler().get(MseaCfmNetconfService.class));
MaintenanceAssociationEndPoint mep =
new DefaultMaintenanceAssociationEndPoint();
mep.mepIdentifier(MepIdType.of(mepId.id()));
org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain
.MaintenanceAssociation yangMa = new DefaultMaintenanceAssociation();
yangMa.maNameAndTypeCombo(MaNameUtil.getYangMaNameFromApiMaId(maName));
yangMa.addToMaintenanceAssociationEndPoint(mep);
org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.MaintenanceDomain yangMd =
new DefaultMaintenanceDomain();
yangMd.mdNameAndTypeCombo(getYangMdNameFromApiMdId(mdName));
yangMd.addToMaintenanceAssociation(yangMa);
MefCfm mefCfm = new DefaultMefCfm();
mefCfm.addToMaintenanceDomain(yangMd);
MseaCfmOpParam mseaCfmOpParam = new MseaCfmOpParam();
mseaCfmOpParam.mefCfm(mefCfm);
try {
mseaCfmService.deleteMseaMep(mseaCfmOpParam, session, DatastoreId.RUNNING);
log.info("Deleted MEP {} on device {}", mdName + "/" + maName +
"/" + mepId, handler().data().deviceId());
return true;
} catch (NetconfException e) {
log.error("Unable to delete MEP {}/{}/{} on device {}",
mdName, maName, mepId, handler().data().deviceId());
throw new CfmConfigException("Unable to delete MEP :" + e.getMessage());
}
}
@Override
public void transmitLoopback(MdId mdName, MaIdShort maName, MepId mepId,
MepLbCreate lbCreate) throws CfmConfigException {
NetconfController controller =
checkNotNull(handler().get(NetconfController.class));
NetconfSession session = controller.getDevicesMap()
.get(handler().data().deviceId()).getSession();
MseaCfmNetconfService mseaCfmService =
checkNotNull(handler().get(MseaCfmNetconfService.class));
CfmMdService mdService = checkNotNull(handler().get(CfmMdService.class));
Short mdNumericId = mdService.getMaintenanceDomain(mdName).get().mdNumericId();
Short maNumericId =
mdService.getMaintenanceAssociation(mdName, maName).get().maNumericId();
TransmitLoopbackInput lb = new DefaultTransmitLoopbackInput();
lb.maintenanceDomain(mdNumericId);
lb.maintenanceAssociation(maNumericId);
lb.maintenanceAssociationEndPoint(mepId.id());
if (lbCreate.numberMessages() != null) {
lb.numberOfMessages(lbCreate.numberMessages());
}
if (lbCreate.vlanDropEligible() != null) {
lb.vlanDropEligible(lbCreate.vlanDropEligible());
}
if (lbCreate.remoteMepId() != null) {
org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.targetaddressgroup.addresstype
.MepId yangMepId = new DefaultMepId();
yangMepId.mepId(MepIdType.of(lbCreate.remoteMepId().id()));
TargetAddress ta = new DefaultTargetAddress();
ta.addressType(yangMepId);
lb.targetAddress(ta);
} else if (lbCreate.remoteMepAddress() != null) {
org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.targetaddressgroup.addresstype
.MacAddress yangMacAddress = new DefaultMacAddress();
yangMacAddress.macAddress(
org.onosproject.yang.gen.v1.ietfyangtypes.rev20130715.ietfyangtypes
.MacAddress.of(lbCreate.remoteMepAddress().toString()));
TargetAddress ta = new DefaultTargetAddress();
ta.addressType(yangMacAddress);
lb.targetAddress(ta);
} else {
throw new CfmConfigException("Either a remote MEP ID or Remote MEP "
+ "MacAddress must be specified when calling Transmit Loopback");
}
if (lbCreate.dataTlvHex() != null && !lbCreate.dataTlvHex().isEmpty()) {
lb.dataTlv(HexString.fromHexString(lbCreate.dataTlvHex()));
}
if (lbCreate.vlanPriority() != null) {
lb.vlanPriority(PriorityType.of((short) lbCreate.vlanPriority().ordinal()));
}
try {
mseaCfmService.transmitLoopback(lb, session);
log.info("Transmit Loopback called on MEP {} on device {}",
mdName + "/" + maName + "/" + mepId,
handler().data().deviceId());
} catch (NetconfException e) {
throw new CfmConfigException(e);
}
}
@Override
public void abortLoopback(MdId mdName, MaIdShort maName, MepId mepId)
throws CfmConfigException {
NetconfController controller =
checkNotNull(handler().get(NetconfController.class));
NetconfSession session = controller.getDevicesMap()
.get(handler().data().deviceId()).getSession();
MseaCfmNetconfService mseaCfmService =
checkNotNull(handler().get(MseaCfmNetconfService.class));
CfmMdService mdService = checkNotNull(handler().get(CfmMdService.class));
Short mdNumericId = mdService.getMaintenanceDomain(mdName).get().mdNumericId();
Short maNumericId =
mdService.getMaintenanceAssociation(mdName, maName).get().maNumericId();
AbortLoopbackInput lbAbort = new DefaultAbortLoopbackInput();
lbAbort.maintenanceDomain(mdNumericId);
lbAbort.maintenanceAssociation(maNumericId);
lbAbort.maintenanceAssociationEndPoint(mepId.id());
try {
mseaCfmService.abortLoopback(lbAbort, session);
log.info("Loopback on MEP {} on device {} aborted",
mdName + "/" + maName + "/" + mepId,
handler().data().deviceId());
} catch (NetconfException e) {
throw new CfmConfigException(e);
}
}
@Override
public void transmitLinktrace(MdId mdName, MaIdShort maName, MepId mepId,
MepLtCreate ltCreate) {
throw new UnsupportedOperationException("Not yet implemented");
}
private org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm
.MaintenanceDomain buildYangMdFromApiMd(MaintenanceDomain md)
throws CfmConfigException {
MdNameAndTypeCombo mdName = getYangMdNameFromApiMdId(md.mdId());
org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm
.MaintenanceDomain mdYang = new DefaultMaintenanceDomain();
mdYang.id(md.mdNumericId());
mdYang.mdNameAndTypeCombo(mdName);
mdYang.mdLevel(MdLevelType.of((short) md.mdLevel().ordinal()));
return mdYang;
}
protected static MdNameAndTypeCombo getYangMdNameFromApiMdId(MdId mdId)
throws CfmConfigException {
MdNameAndTypeCombo mdName;
if (mdId instanceof MdIdDomainName) {
boolean isIpAddr = false;
try {
if (IpAddress.valueOf(mdId.mdName()) != null) {
isIpAddr = true;
}
} catch (IllegalArgumentException e) {
//continue
}
if (isIpAddr) {
mdName = new DefaultNameDomainName();
((DefaultNameDomainName) mdName).nameDomainName(NameDomainNameUnion.of(
org.onosproject.yang.gen.v1.ietfinettypes.rev20130715.ietfinettypes.
IpAddress.fromString(mdId.mdName())));
} else {
mdName = new DefaultNameDomainName();
((DefaultNameDomainName) mdName).nameDomainName(NameDomainNameUnion
.of(DomainName.fromString(mdId.mdName())));
}
} else if (mdId instanceof MdIdMacUint) {
mdName = new DefaultMacAddressAndUint();
((DefaultMacAddressAndUint) mdName).nameMacAddressAndUint(MacAddressAndUintStr.fromString(mdId.mdName()));
} else if (mdId instanceof MdIdNone) {
mdName = new DefaultNameNone();
} else if (mdId instanceof MdIdCharStr) {
mdName = new DefaultNameCharacterString();
((DefaultNameCharacterString) mdName).name(Identifier45.fromString(mdId.mdName()));
} else {
throw new CfmConfigException("Unexpected error creating MD " +
mdId.getClass().getSimpleName());
}
return mdName;
}
private org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm
.maintenancedomain.MaintenanceAssociation buildYangMaFromApiMa(
MaintenanceAssociation apiMa) throws CfmConfigException {
MaNameAndTypeCombo maName = MaNameUtil.getYangMaNameFromApiMaId(apiMa.maId());
org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain
.MaintenanceAssociation yamgMa = new DefaultMaintenanceAssociation();
yamgMa.maNameAndTypeCombo(maName);
if (apiMa.remoteMepIdList() == null || apiMa.remoteMepIdList().size() < REMOTEMEPLIST_MIN_COUNT
|| apiMa.remoteMepIdList().size() > REMOTEMEPLIST_MAX_COUNT) {
throw new CfmConfigException("EA1000 requires between " +
REMOTEMEPLIST_MIN_COUNT + " and " + REMOTEMEPLIST_MAX_COUNT +
" remote meps in an MA");
}
for (MepId rmep:apiMa.remoteMepIdList()) {
yamgMa.addToRemoteMeps(MepIdType.of(rmep.id()));
}
if (apiMa.ccmInterval() != null) {
switch (apiMa.ccmInterval()) {
case INTERVAL_3MS:
yamgMa.ccmInterval(CcmIntervalEnum.YANGAUTOPREFIX3_3MS);
break;
case INVERVAL_10MS:
yamgMa.ccmInterval(CcmIntervalEnum.YANGAUTOPREFIX10MS);
break;
case INVERVAL_100MS:
yamgMa.ccmInterval(CcmIntervalEnum.YANGAUTOPREFIX100MS);
break;
case INTERVAL_1S:
yamgMa.ccmInterval(CcmIntervalEnum.YANGAUTOPREFIX1S);
break;
default:
throw new CfmConfigException("EA1000 only supports "
+ "3ms, 10ms, 100ms and 1s for CCM Interval. Rejecting: "
+ apiMa.ccmInterval().name());
}
}
if (apiMa.componentList() == null || apiMa.componentList().size() != COMPONENT_LIST_SIZE) {
throw new CfmConfigException("EA1000 supports only 1 Component in an MA");
}
Component maComponent = apiMa.componentList().iterator().next();
if (maComponent.vidList() == null || maComponent.vidList().size() < VIDLIST_SIZE_MIN) {
throw new CfmConfigException("EA1000 requires at least 1 VID in "
+ "the Component of an MA");
}
ComponentList compList = new DefaultComponentList();
for (VlanId vid:maComponent.vidList()) {
compList.addToVid(VlanIdType.of(vid.toShort()));
}
if (maComponent.tagType() != null) {
switch (maComponent.tagType()) {
case VLAN_STAG:
compList.tagType(TagTypeEnum.VLAN_STAG);
break;
case VLAN_CTAG:
compList.tagType(TagTypeEnum.VLAN_CTAG);
break;
case VLAN_NONE:
default:
compList.tagType(TagTypeEnum.VLAN_NONE);
break;
}
}
yamgMa.componentList(compList);
yamgMa.id(apiMa.maNumericId());
return yamgMa;
}
private MaintenanceAssociationEndPoint buildYangMepFromApiMep(Mep mep)
throws CfmConfigException {
MaintenanceAssociationEndPoint mepBuilder =
new DefaultMaintenanceAssociationEndPoint();
mepBuilder.mepIdentifier(MepIdType.of(mep.mepId().id()));
ContinuityCheck cc = new DefaultContinuityCheck();
cc.cciEnabled(mep.cciEnabled());
mepBuilder.continuityCheck(cc);
mepBuilder.ccmLtmPriority(
PriorityType.of((short) mep.ccmLtmPriority().ordinal()));
mepBuilder.administrativeState(mep.administrativeState());
if (mep.direction() == MepDirection.UP_MEP) {
throw new CfmConfigException("EA1000 only supports DOWN Meps");
}
if (mep.port() == null || mep.port().toLong() < MEP_PORT_MIN
|| mep.port().toLong() > MEP_PORT_MAX) {
throw new CfmConfigException("EA1000 has only ports 0 and 1. "
+ "Rejecting Port: " + mep.port());
}
mepBuilder.yangAutoPrefixInterface(
(mep.port().toLong() == 0) ? InterfaceEnum.ETH0 : InterfaceEnum.ETH1);
return mepBuilder;
}
private MepEntry buildApiMepEntryFromYangMep(
MaintenanceAssociationEndPoint yangMep, DeviceId deviceId,
MdId mdName, MaIdShort maName) throws CfmConfigException {
MepId mepId = MepId.valueOf((short) yangMep.mepIdentifier().uint16());
MepEntry.MepEntryBuilder builder = DefaultMepEntry.builder(mepId,
deviceId,
(yangMep.yangAutoPrefixInterface() == InterfaceEnum.ETH0) ?
PortNumber.portNumber(0) : PortNumber.portNumber(1),
MepDirection.DOWN_MEP, //Always down for EA1000
mdName, maName);
if (yangMep.loopback() != null) {
MepLbEntryBuilder lbEntryBuilder = DefaultMepLbEntry.builder();
if (yangMep.loopback().repliesReceived() != null) {
lbEntryBuilder = lbEntryBuilder.countLbrReceived(
yangMep.loopback().repliesReceived().uint32());
}
if (yangMep.loopback().repliesTransmitted() != null) {
lbEntryBuilder = lbEntryBuilder.countLbrTransmitted(
yangMep.loopback().repliesTransmitted().uint32());
}
builder.loopbackAttributes(lbEntryBuilder.build());
}
if (yangMep.remoteMepDatabase() != null &&
yangMep.remoteMepDatabase().remoteMep() != null) {
for (org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm
.maintenancedomain.maintenanceassociation
.maintenanceassociationendpoint.remotemepdatabase.RemoteMep
rmep:yangMep.remoteMepDatabase().remoteMep()) {
builder = (MepEntry.MepEntryBuilder) builder.addToActiveRemoteMepList(
getApiRemoteMepFromYangRemoteMep(rmep));
}
}
if (yangMep.ccmLtmPriority() != null) {
builder = (MepEntry.MepEntryBuilder) builder.ccmLtmPriority(
Priority.values()[yangMep.ccmLtmPriority().uint8()]);
}
//And the the state attributes
builder = (MepEntry.MepEntryBuilder) builder
.macAddress(MacAddress.valueOf(yangMep.macAddress().toString()))
.administrativeState(yangMep.administrativeState())
.cciEnabled(yangMep.continuityCheck().cciEnabled());
AugmentedMseaCfmMaintenanceAssociationEndPoint augmentedyangMep = yangMep
.augmentation(DefaultAugmentedMseaCfmMaintenanceAssociationEndPoint.class);
if (augmentedyangMep != null) {
if (augmentedyangMep.lastDefectSent() != null) {
builder = (MepEntry.MepEntryBuilder) builder
.activeXconCcmDefect(augmentedyangMep.lastDefectSent().bits()
.get(Bits.CROSS_CONNECT_CCM.bits()))
.activeErrorCcmDefect(augmentedyangMep.lastDefectSent().bits()
.get(Bits.INVALID_CCM.bits()))
.activeMacStatusDefect(augmentedyangMep.lastDefectSent().bits()
.get(Bits.REMOTE_MAC_ERROR.bits()))
.activeRdiCcmDefect(augmentedyangMep.lastDefectSent().bits()
.get(Bits.REMOTE_RDI.bits()))
.activeRemoteCcmDefect(augmentedyangMep.lastDefectSent().bits()
.get(Bits.REMOTE_INVALID_CCM.bits()));
}
}
return builder.buildEntry();
}
private RemoteMepEntry getApiRemoteMepFromYangRemoteMep(
org.onosproject.yang.gen.v1.mseacfm.rev20160229.mseacfm.mefcfm.maintenancedomain.
maintenanceassociation.maintenanceassociationendpoint.remotemepdatabase.
RemoteMep yangRemoteMep) throws CfmConfigException {
MepId remoteMepId = MepId.valueOf((short) yangRemoteMep.remoteMepId().uint16());
RemoteMepStateTypeEnum state = RemoteMepStateTypeEnum.FAILED;
if (yangRemoteMep.remoteMepState() != null) {
state = yangRemoteMep.remoteMepState().enumeration();
}
RemoteMepEntryBuilder rmepBuilder = DefaultRemoteMepEntry.builder(
remoteMepId, RemoteMepState.valueOf("RMEP_" + state.name()))
.rdi(yangRemoteMep.rdi());
if (yangRemoteMep.macAddress() != null) {
rmepBuilder = rmepBuilder.macAddress(
MacAddress.valueOf(yangRemoteMep.macAddress().toString()));
}
if (yangRemoteMep.failedOkTime() != null) {
//Currently EA1000 is reporting this as 1/1000s even though yang type
// is time ticks 1/100s - to be fixed
rmepBuilder = rmepBuilder.failedOrOkTime(Duration.ofMillis(
yangRemoteMep.failedOkTime().uint32()));
}
if (yangRemoteMep.portStatusTlv() != null) {
rmepBuilder = rmepBuilder.portStatusTlvType(PortStatusTlvType.valueOf(
"PS_" + yangRemoteMep.portStatusTlv().enumeration().name()));
}
if (yangRemoteMep.interfaceStatusTlv() != null) {
rmepBuilder = rmepBuilder.interfaceStatusTlvType(InterfaceStatusTlvType.valueOf(
"IS_" + yangRemoteMep.interfaceStatusTlv().enumeration().name()));
}
return rmepBuilder.build();
}
}