return (BigInteger.valueOf(elanTag)).shiftLeft(24);
}
- public static BigInteger getElanMetadataMask() {
- return MetaDataUtil.METADATA_MASK_SERVICE.or(MetaDataUtil.METADATA_MASK_LPORT_TAG);
- }
-
-
- /* This flow is in charge of handling packets coming from ExtTunnelTable
+ /**
+ * This flow is in charge of handling packets coming from ExtTunnelTable
* that must be redirected to the SCF Pipeline.
* + Matches on lportTag=ElanPseudoLportTag + SI=1
* + Sets scfTag and sends to the DlSubsFilter table.
*
- * @param dpnId
- * @param elanLportTag
- * @param elanTag
- * @param addOrRemove
+ * @param dpnId Dpn Id where the LPortDispatcher table must be modified
+ * @param elanLportTag Dataplane identifier of the ElanPseudoPort
+ * @param elanTag Dataplane identifier of the ELAN
+ * @param addOrRemove States if flows must be added or removed
*/
public static void programLPortDispatcherToScf(IMdsalApiManager mdsalManager, BigInteger dpnId, int elanTag,
int elanLportTag, short tableId, int scfTag, int addOrRemove) {
}
}
- /* This flow is in charge of handling packets coming from the SCF Pipeline
+ /**
+ * This flow is in charge of handling packets coming from the SCF Pipeline
* when there is no matching ServiceChain.
*
* + Matches on ElanPseudoPortTag and SI=3 (ELAN)
* + Sets elanTag and sends to DMAC table
*
- * @param dpnId
- * @param elanLportTag
- * @param elanTag
- * @param addOrRemove
+ * @param dpnId Dpn Id where the LPortDispatcher table must be modified
+ * @param elanLportTag Dataplane identifier of the ElanPseudoPort
+ * @param elanTag Dataplane identifier of the ELAN
+ * @param addOrRemove States if flows must be added or removed
*/
public static void programLPortDispatcherFromScf(IMdsalApiManager mdsalManager, BigInteger dpnId,
- int elanLportTag, int elanTag, int addOrRemove) {
+ int elanLportTag, int elanTag, int addOrRemove) {
logger.info("L2-ServiceChaining: programLPortDispatcherFromScf dpId={} elanLportTag={} elanTag={} addOrRemove={} ",
dpnId, elanLportTag, elanTag, addOrRemove);
String flowRef = buildLportDispFromScfFlowRef(elanTag, elanLportTag );
if (addOrRemove == NwConstants.ADD_FLOW) {
List<MatchInfo> matches = Arrays.asList(
new MatchInfo(MatchFieldType.metadata,
- new BigInteger[] { MetaDataUtil.getMetaDataForLPortDispatcher(elanLportTag,
- NwConstants.ELAN_SERVICE_INDEX)
- .or(BigInteger.ONE), // SH FLag
- MetaDataUtil.getMetaDataMaskForLPortDispatcher()
- .or(BigInteger.ONE) })); // Bit mask for SH Flag
+ new BigInteger[] { MetaDataUtil.getMetaDataForLPortDispatcher(elanLportTag,
+ NwConstants.ELAN_SERVICE_INDEX),
+ MetaDataUtil.getMetaDataMaskForLPortDispatcher() }));
int instructionKey = 0;
List<Instruction> instructions = Arrays.asList(
- MDSALUtil.buildAndGetWriteMetadaInstruction(ElanServiceChainUtils.getElanMetadataLabel(elanTag),
- ElanServiceChainUtils.getElanMetadataMask(),
+ // BigInter.ONE is for setting also the Split-Horizon flag since it could have been cleared
+ // while going through the SCF Pipeline
+ MDSALUtil.buildAndGetWriteMetadaInstruction(getElanMetadataLabel(elanTag).or(BigInteger.ONE),
+ MetaDataUtil.METADATA_MASK_SERVICE.or(BigInteger.ONE),
instructionKey++),
- MDSALUtil.buildAndGetGotoTableInstruction(NwConstants.ELAN_DMAC_TABLE, instructionKey++) );
+ MDSALUtil.buildAndGetGotoTableInstruction(NwConstants.ELAN_SMAC_TABLE,
+ instructionKey++) );
- Flow flow = MDSALUtil.buildFlowNew(NwConstants.LPORT_DISPATCHER_TABLE, flowRef,
- CloudServiceChainConstants.DEFAULT_LPORT_DISPATCHER_FLOW_PRIORITY,
- flowRef, 0, 0,
- ITMConstants.COOKIE_ITM_EXTERNAL.add(BigInteger.valueOf(elanTag)),
- matches, instructions);
+ Flow flow =
+ MDSALUtil.buildFlowNew(NwConstants.LPORT_DISPATCHER_TABLE, flowRef,
+ CloudServiceChainConstants.DEFAULT_LPORT_DISPATCHER_FLOW_PRIORITY,
+ flowRef, 0, 0, ITMConstants.COOKIE_ITM_EXTERNAL.add(BigInteger.valueOf(elanTag)),
+ matches, instructions);
mdsalManager.installFlow(dpnId, flow);
} else {
Flow flow = new FlowBuilder().setTableId(NwConstants.LPORT_DISPATCHER_TABLE)
}
- /* This flow is in charge of receiving packets from the TOR and sending
+ /**
+ * This flow is in charge of receiving packets from the TOR and sending
* them to the SCF Pipeline by setting the LportTag of ElanPseudoPort.
* Note that ELAN already has a flow in this table that redirects packets
* to the ELAN Pipeline. However, the flow for the SCF Pipeline will have
* using this ElanPseudoPort.
*
* + Matches on the VNI
- * + Sets the ElanPseudoPort tag in the Metadata and sends to
+ * + Sets SI=1 and ElanPseudoPort tag in the Metadata and sends to
* LPortDispatcher via table 80.
*
- * @param dpnId
- * @param elanLportTag
- * @param vni
- * @param elanTag
- * @param addOrRemove
+ * @param dpnId Dpn Id where the ExtTunnel table must be modified
+ * @param elanLportTag Dataplane identifier of the ElanPseudoPort
+ * @param vni Virtual Network Identifier
+ * @param elanTag Dataplane identifier of the ELAN
+ * @param addOrRemove States if flows must be added or removed
*/
public static void programExternalTunnelTable(IMdsalApiManager mdsalManager, BigInteger dpnId, int elanLportTag,
Long vni, int elanTag, int addOrRemove) {
* Builds a List of Instructions that set the ElanPseudoPort Tag in
* metadata and sends to LPortDispatcher table (via Table 80)
*
- * @param lportTag LPortTag of the ElanPseudoPort
+ * @param lportTag Dataplane identifier of the ElanPseudoPort
*
* @return the List of Instructions
*/
public static List<Instruction> buildSetLportTagAndGotoLportDispInstructions(long lportTag) {
int instructionKey = 0;
+ BigInteger metadata = MetaDataUtil.getMetaDataForLPortDispatcher((int) lportTag,
+ NwConstants.SCF_SERVICE_INDEX);
List<Instruction> result =
- Arrays.asList(MDSALUtil.buildAndGetWriteMetadaInstruction(MetaDataUtil.getLportTagMetaData((int) lportTag),
+ Arrays.asList(MDSALUtil.buildAndGetWriteMetadaInstruction(metadata,
MetaDataUtil.getMetaDataMaskForLPortDispatcher(),
++instructionKey),
MDSALUtil.buildAndGetGotoTableInstruction(NwConstants.L3_INTERFACE_TABLE, ++instructionKey));
/**
* Stores the relation between elanInstanceName and ElanLport and scfTag.
*
- * @param broker
- * @param elanInstanceName
- * @param lportTag
- * @param scfTag
- * @param addOrRemove
+ * @param broker dataBroker service reference
+ * @param elanInstanceName Name of the ELAN. Typically its UUID
+ * @param lportTag Dataplane identifier of the ElanPseudoPort
+ * @param scfTag Dataplane identifier of the SCF
+ * @param addOrRemove States if flows must be added or removed
*/
public static void updateElanToLportTagMap(final DataBroker broker, final String elanInstanceName,
final int lportTag, final int scfTag, final int addOrRemove) {
/**
* Read from ElanToLportTagMap the PsuedoLogicalPort related with a given elan.
*
- * @param broker
+ * @param broker dataBroker service reference
* @param elanInstanceName
- * @return Optional containing ElanToPseudoPortData
+ * @return the ElanToPseudoPortData object or Optional.absent() if it
+ * cannot be found
*/
public static Optional<ElanToPseudoPortData> getElanToLportTagList(final DataBroker broker, final String elanInstanceName) {
ElanToPseudoPortDataKey key = new ElanToPseudoPortDataKey(elanInstanceName);
private final IBgpManager bgpManager;
private final NotificationPublishService notificationsService;
private static final String NBR_OF_DPNS_PROPERTY_NAME = "vpnservice.intervpnlink.number.dpns";
- private static final int INVALID_ID = 0;
+ private static final long INVALID_ID = 0;
public InterVpnLinkListener(final DataBroker dataBroker, final IdManagerService idManager,
final IMdsalApiManager mdsalManager, final IBgpManager bgpManager,
@Override
protected void add(InstanceIdentifier<InterVpnLink> identifier, InterVpnLink add) {
+ LOG.debug("Reacting to IVpnLink {} creation. Vpn1=[name={} EndpointIp={}] Vpn2=[name={} endpointIP={}]",
+ add.getName(), add.getFirstEndpoint().getVpnUuid(), add.getFirstEndpoint().getIpAddress(),
+ add.getSecondEndpoint().getVpnUuid(), add.getSecondEndpoint().getIpAddress());
+
int numberOfDpns = Integer.getInteger(NBR_OF_DPNS_PROPERTY_NAME, 1);
// Create VpnLink state
InstanceIdentifier<InterVpnLinkState> vpnLinkStateIid = VpnUtil.getInterVpnLinkStateIid(add.getName());
Uuid firstEndpointVpnUuid = add.getFirstEndpoint().getVpnUuid();
Uuid secondEndpointVpnUuid = add.getSecondEndpoint().getVpnUuid();
// First VPN
+ if ( VpnUtil.getVpnInstance(this.dataBroker, firstEndpointVpnUuid.getValue()) == null ) {
+ String errMsg = "InterVpnLink " + add.getName() + " creation error: could not find 1st endpoint Vpn "
+ + firstEndpointVpnUuid.getValue();
+ setInError(vpnLinkStateIid, vpnLinkState, errMsg);
+ return;
+ }
if (!checkVpnAvailability(key, firstEndpointVpnUuid)) {
- String errMsg = String.format("Vpn already associated with a previous inter-vpn-link {}",
- firstEndpointVpnUuid);
- LOG.error(errMsg);
+ String errMsg = "InterVpnLink " + add.getName() + " creation error: Vpn " + firstEndpointVpnUuid.getValue()
+ + " is already associated to an inter-vpn-link ";
setInError(vpnLinkStateIid, vpnLinkState, errMsg);
return;
}
// Second VPN
+ if ( VpnUtil.getVpnInstance(this.dataBroker, secondEndpointVpnUuid.getValue()) == null ) {
+ String errMsg = "InterVpnLink " + add.getName() + " creation error: could not find 2nd endpoint Vpn "
+ + secondEndpointVpnUuid.getValue();
+ setInError(vpnLinkStateIid, vpnLinkState, errMsg);
+ return;
+ }
if (!checkVpnAvailability(key, secondEndpointVpnUuid)) {
- String errMsg = String.format("Vpn already associated with a previous inter-vpn-link {}",
- secondEndpointVpnUuid);
- LOG.error(errMsg);
+ String errMsg = "InterVpnLink " + add.getName() + " creation error: Vpn " + secondEndpointVpnUuid.getValue()
+ + " is already associated with an inter-vpn-link";
setInError(vpnLinkStateIid, vpnLinkState, errMsg);
return;
}
// List<BigInteger> secondDpnList = VpnUtil.pickRandomDPNs(dataBroker, numberOfDpns, firstDpnList);
List<BigInteger> secondDpnList = firstDpnList;
- Integer firstVpnLportTag = allocateVpnLinkLportTag(key.getName() + firstEndpointVpnUuid.getValue());
- Integer secondVpnLportTag = allocateVpnLinkLportTag(key.getName() + secondEndpointVpnUuid.getValue());
+ Long firstVpnLportTag = allocateVpnLinkLportTag(key.getName() + firstEndpointVpnUuid.getValue());
+ Long secondVpnLportTag = allocateVpnLinkLportTag(key.getName() + secondEndpointVpnUuid.getValue());
FirstEndpointState firstEndPointState =
new FirstEndpointStateBuilder().setVpnUuid(firstEndpointVpnUuid).setDpId(firstDpnList)
.setLportTag(firstVpnLportTag).build();
} else {
// If there is no connection to DPNs, the InterVpnLink is created and the InterVpnLinkState is also created
// with the corresponding LPortTags but no DPN is assigned since there is no DPN operative.
- Integer firstVpnLportTag = allocateVpnLinkLportTag(key.getName() + firstEndpointVpnUuid.getValue());
- Integer secondVpnLportTag = allocateVpnLinkLportTag(key.getName() + secondEndpointVpnUuid.getValue());
+ Long firstVpnLportTag = allocateVpnLinkLportTag(key.getName() + firstEndpointVpnUuid.getValue());
+ Long secondVpnLportTag = allocateVpnLinkLportTag(key.getName() + secondEndpointVpnUuid.getValue());
FirstEndpointState firstEndPointState =
new FirstEndpointStateBuilder().setVpnUuid(firstEndpointVpnUuid)
.setLportTag(firstVpnLportTag).build();
leakRoutes(vpnLink, vpn1Uuid, vpn2Uuid, originsToConsider);
// 2nd Endpoint ==> 1st endpoint
- leakRoutes(vpnLink, vpnLink.getSecondEndpoint().getVpnUuid().getValue(),
- vpnLink.getFirstEndpoint().getVpnUuid().getValue(),
- originsToConsider);
+ leakRoutes(vpnLink, vpn2Uuid, vpn1Uuid, originsToConsider);
}
// Static routes in Vpn1 pointing to Vpn2's endpoint
@Override
protected void remove(InstanceIdentifier<InterVpnLink> identifier, InterVpnLink del) {
+ LOG.debug("Reacting to InterVpnLink {} removal", del.getName());
// Remove learnt routes
// Remove entries in the LPortDispatcher table
// Remove the corresponding entries in InterVpnLinkState
// For each endpoint, remove all routes that have been learnt by intervpnLink
String vpn1Uuid = del.getFirstEndpoint().getVpnUuid().getValue();
String rd1 = VpnUtil.getVpnRdFromVpnInstanceConfig(dataBroker, vpn1Uuid);
+ LOG.debug("Removing leaked routes in VPN {} rd={}", vpn1Uuid, rd1);
VpnUtil.removeVrfEntriesByOrigin(dataBroker, rd1, RouteOrigin.INTERVPN);
VpnUtil.removeVrfEntriesByNexthop(dataBroker, rd1, del.getSecondEndpoint().getIpAddress().getValue());
String vpn2Uuid = del.getSecondEndpoint().getVpnUuid().getValue();
String rd2 = VpnUtil.getVpnRdFromVpnInstanceConfig(dataBroker, vpn2Uuid);
+ LOG.debug("Removing leaked routes in VPN {} rd={}", vpn2Uuid, rd2);
VpnUtil.removeVrfEntriesByOrigin(dataBroker, rd2, RouteOrigin.INTERVPN);
VpnUtil.removeVrfEntriesByNexthop(dataBroker, rd2, del.getFirstEndpoint().getIpAddress().getValue());
InterVpnLinkState interVpnLinkState = VpnUtil.getInterVpnLinkState(dataBroker, del.getName());
- Integer firstEndpointLportTag = interVpnLinkState.getFirstEndpointState().getLportTag();
-
- Integer secondEndpointLportTag = interVpnLinkState.getSecondEndpointState().getLportTag();
-
- // Remmoving the flow entries in LPortDispatcher table in 1st Endpoint DPNs
- for ( BigInteger dpnId : interVpnLinkState.getFirstEndpointState().getDpId() ) {
- String flowRef = InterVpnLinkUtil.getLportDispatcherFlowRef(del.getName(), secondEndpointLportTag);
- FlowKey flowKey = new FlowKey(new FlowId(flowRef));
- Flow flow = new FlowBuilder().setKey(flowKey).setId(new FlowId(flowRef))
- .setTableId(NwConstants.LPORT_DISPATCHER_TABLE).setFlowName(flowRef)
- .build();
- mdsalManager.removeFlow(dpnId, flow);
-
- // Also remove the 'fake' iface from the VpnToDpn map
- VpnUtil.removeIfaceFromVpnToDpnMap(dataBroker, rd1, dpnId, getInterVpnLinkIfaceName(vpn1Uuid, dpnId));
- }
-
- // Removing the flow entries in 2nd Endpoint DPNs
- for ( BigInteger dpnId : interVpnLinkState.getSecondEndpointState().getDpId() ) {
- String flowRef = InterVpnLinkUtil.getLportDispatcherFlowRef(del.getName(), firstEndpointLportTag);
- FlowKey flowKey = new FlowKey(new FlowId(flowRef));
- Flow flow = new FlowBuilder().setKey(flowKey).setId(new FlowId(flowRef))
- .setTableId(NwConstants.LPORT_DISPATCHER_TABLE).setFlowName(flowRef)
- .build();
- mdsalManager.removeFlow(dpnId, flow);
-
- // Also remove the 'fake' iface from the VpnToDpn map
- VpnUtil.removeIfaceFromVpnToDpnMap(dataBroker, rd2, dpnId, getInterVpnLinkIfaceName(vpn2Uuid, dpnId));
- }
-
- // Release idManager wit LPortTag associated to endpoints
+ Long firstEndpointLportTag = interVpnLinkState.getFirstEndpointState().getLportTag();
+ Long secondEndpointLportTag = interVpnLinkState.getSecondEndpointState().getLportTag();
+ removeVpnLinkEndpointFlows(del.getName(), rd1, vpn1Uuid, interVpnLinkState.getFirstEndpointState().getDpId(),
+ secondEndpointLportTag.intValue(),
+ del.getSecondEndpoint().getIpAddress().getValue());
+ removeVpnLinkEndpointFlows(del.getName(), rd2, vpn2Uuid, interVpnLinkState.getSecondEndpointState().getDpId(),
+ firstEndpointLportTag.intValue(), del.getFirstEndpoint().getIpAddress().getValue());
+
+ // Release idManager with LPortTag associated to endpoints
+ LOG.debug("Releasing InterVpnLink {} endpoints LportTags", del.getName());
InterVpnLinkKey key = del.getKey();
Uuid firstEndpointVpnUuid = del.getFirstEndpoint().getVpnUuid();
Uuid secondEndpointVpnUuid = del.getSecondEndpoint().getVpnUuid();
// At this point. we need to check if is there any entry in FIB table pointing to LPortDispatcher table.
// Remove it in that case.
- // 1stEndPoint dpns
- for ( BigInteger dpnId : interVpnLinkState.getFirstEndpointState().getDpId() ) {
- removeRouteFromInterVpnLink(dpnId, del.getName(), del.getSecondEndpoint().getIpAddress().getValue());
- }
-
- // 2ndtEndPoint dpns
- for ( BigInteger dpnId : interVpnLinkState.getSecondEndpointState().getDpId() ) {
- removeRouteFromInterVpnLink(dpnId, del.getName(), del.getFirstEndpoint().getIpAddress().getValue());
- }
-
// Removing the InterVpnLinkState
InstanceIdentifier<InterVpnLinkState> interVpnLinkStateIid = VpnUtil.getInterVpnLinkStateIid(del.getName());
VpnUtil.delete(dataBroker, LogicalDatastoreType.CONFIGURATION, interVpnLinkStateIid);
}
+ private void removeVpnLinkEndpointFlows( String interVpnLinkName, String rd, String vpnUuid, List<BigInteger> dpns,
+ int otherEndpointLportTag, String otherEndpointIpAddr ) {
+ LOG.debug("Removing endpoint flows for vpn {}. InterVpnLink={}. OtherEndpointLportTag={}",
+ vpnUuid, interVpnLinkName, otherEndpointLportTag);
+ if ( dpns == null ) {
+ LOG.debug("VPN {} endpoint is not instantiated in any DPN for InterVpnLink {}",
+ vpnUuid, interVpnLinkName);
+ return;
+ }
+
+ for ( BigInteger dpnId : dpns ) {
+ try {
+ // Removing flow from LportDispatcher table
+ String flowRef = InterVpnLinkUtil.getLportDispatcherFlowRef(interVpnLinkName, otherEndpointLportTag);
+ FlowKey flowKey = new FlowKey(new FlowId(flowRef));
+ Flow flow = new FlowBuilder().setKey(flowKey).setId(new FlowId(flowRef))
+ .setTableId(NwConstants.LPORT_DISPATCHER_TABLE).setFlowName(flowRef)
+ .build();
+ mdsalManager.removeFlow(dpnId, flow);
+
+ // Removing flow from Fib table
+ String fibFlowRef = getInterVpnFibFlowRef(dpnId, NwConstants.L3_FIB_TABLE, interVpnLinkName,
+ otherEndpointIpAddr);
+ FlowKey fibFlowKey = new FlowKey(new FlowId(fibFlowRef));
+ Flow fibFlow = new FlowBuilder().setKey(fibFlowKey).setId(new FlowId(fibFlowRef))
+ .setTableId(NwConstants.L3_FIB_TABLE).setFlowName(fibFlowRef).build();
+ mdsalManager.removeFlow(dpnId, fibFlow);
+
+ // Also remove the 'fake' iface from the VpnToDpn map
+ VpnUtil.removeIfaceFromVpnToDpnMap(dataBroker, rd, dpnId, getInterVpnLinkIfaceName(vpnUuid, dpnId));
+
+ } catch ( Exception e ) {
+ // Whatever happens it should not stop it from trying to remove as much as possible
+ LOG.warn("Error while removing InterVpnLink {} Endpoint flows on dpn {}. Reason: {}",
+ interVpnLinkName, dpnId, e);
+ }
+ }
+ }
+
private void releaseVpnLinkLPortTag(String idKey) {
ReleaseIdInput releaseIdInput =
new ReleaseIdInputBuilder().setPoolName(VpnConstants.PSEUDO_LPORT_TAG_ID_POOL_NAME).setIdKey(idKey).build();
// TODO
}
- private String getInterVpnFibFlowRef(BigInteger dpnId, short tableId, String interVpnLinkName, String nextHop ) {
- return new StringBuilder(64).append(VpnConstants.FLOWID_PREFIX).append(dpnId).append(NwConstants.FLOWID_SEPARATOR)
- .append(tableId).append(NwConstants.FLOWID_SEPARATOR)
- .append(interVpnLinkName).append(NwConstants.FLOWID_SEPARATOR)
- .append(nextHop).toString();
+ private String getInterVpnFibFlowRef(BigInteger dpnId, short tableId, String interVpnLinkName, String nextHop ) {
+ return new StringBuilder(64).append(VpnConstants.FLOWID_PREFIX).append(dpnId)
+ .append(NwConstants.FLOWID_SEPARATOR).append(tableId)
+ .append(NwConstants.FLOWID_SEPARATOR).append(interVpnLinkName)
+ .append(NwConstants.FLOWID_SEPARATOR).append(nextHop)
+ .toString();
}
- private void removeRouteFromInterVpnLink(BigInteger dpnId, String interVpnLinkName, final String nextHop) {
- String flowRef = getInterVpnFibFlowRef(dpnId, NwConstants.L3_FIB_TABLE, interVpnLinkName, nextHop);
- FlowKey flowKey = new FlowKey(new FlowId(flowRef));
- Flow flow = new FlowBuilder().setKey(flowKey).setId(new FlowId(flowRef))
- .setTableId(NwConstants.L3_FIB_TABLE).setFlowName(flowRef)
- .build();
- mdsalManager.removeFlow(dpnId, flow);
- }
-
-
- private Integer allocateVpnLinkLportTag(String idKey) {
+ private Long allocateVpnLinkLportTag(String idKey) {
AllocateIdInput getIdInput =
new AllocateIdInputBuilder().setPoolName(VpnConstants.PSEUDO_LPORT_TAG_ID_POOL_NAME)
.setIdKey(idKey)
Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
RpcResult<AllocateIdOutput> rpcResult = result.get();
if (rpcResult.isSuccessful()) {
- return rpcResult.getResult().getIdValue().intValue();
+ return rpcResult.getResult().getIdValue();
} else {
LOG.warn("RPC Call to Get Unique Id returned with Errors {}", rpcResult.getErrors());
}
protected void setInError(final InstanceIdentifier<InterVpnLinkState> vpnLinkStateIid,
final InterVpnLinkState vpnLinkState,
String errorMsg) {
+ LOG.error("Setting InterVpnLink {} in error. Reason: {}", vpnLinkState.getInterVpnLinkName(), errorMsg);
// Setting InterVPNLink in error state in MDSAL
InterVpnLinkState vpnLinkErrorState =
new InterVpnLinkStateBuilder(vpnLinkState).setState(InterVpnLinkState.State.Error)