From: Suraj Ranjan Date: Sat, 20 Aug 2016 07:34:10 +0000 (+0530) Subject: BUG 6487: Extra routes to IVpnLink endpoint not in FIB X-Git-Tag: release/carbon~870 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=e31df100a362f78cf927368bf6d328c000a4c49f;p=netvirt.git BUG 6487: Extra routes to IVpnLink endpoint not in FIB + LportTag range for InterVpnLink endpoints has changed to a range of [170001..270000]. Those values does not fit in a uint16 attribute + Also applies a bit of refactoring to reduce the duplication of code as much as possible + It also aligns the system properties names to the ones defined in sdnc repository Apart from above bug fix this commit also deals with: 1> Fixes in metadata writing 2> InterVpnLink Active even if VPN not exists Change-Id: Iafe72a651153a7ca48e68748c6b7b271541e835c Signed-off-by: Suraj Ranjan --- diff --git a/vpnservice/cloud-servicechain/cloud-servicechain-impl/src/main/java/org/opendaylight/netvirt/cloudservicechain/CloudServiceChainConstants.java b/vpnservice/cloud-servicechain/cloud-servicechain-impl/src/main/java/org/opendaylight/netvirt/cloudservicechain/CloudServiceChainConstants.java index 6889a080b6..101ec8485b 100644 --- a/vpnservice/cloud-servicechain/cloud-servicechain-impl/src/main/java/org/opendaylight/netvirt/cloudservicechain/CloudServiceChainConstants.java +++ b/vpnservice/cloud-servicechain/cloud-servicechain-impl/src/main/java/org/opendaylight/netvirt/cloudservicechain/CloudServiceChainConstants.java @@ -29,10 +29,6 @@ public class CloudServiceChainConstants { public static final String VPN_PSEUDO_SCF2VPN_FLOWID_PREFIX = "VpnPseudoPort.Scf2Vpn"; public static final String ELAN_TO_SCF_L2_FLOWID_PREFIX = "ElanPseudoPort.Elan2Scf"; public static final String SCF_TO_ELAN_L2_FLOWID_PREFIX = "ElanPseudoPort.Scf2Elan"; - public static final String SCF_L3VPN_IDPOOL_NAME = "l3vpnscf"; - public static final long SCF_L3VPN_ID_POOL_START = 20000; - public static final long SCF_L3VPN_ID_POOL_END = 65535; - public static final long ETHERTYPE_IPV4 = 0x0800L; public static final long INVALID_VPN_TAG = -1; } diff --git a/vpnservice/cloud-servicechain/cloud-servicechain-impl/src/main/java/org/opendaylight/netvirt/cloudservicechain/utils/ElanServiceChainUtils.java b/vpnservice/cloud-servicechain/cloud-servicechain-impl/src/main/java/org/opendaylight/netvirt/cloudservicechain/utils/ElanServiceChainUtils.java index 5a319b9749..0042d63dfc 100644 --- a/vpnservice/cloud-servicechain/cloud-servicechain-impl/src/main/java/org/opendaylight/netvirt/cloudservicechain/utils/ElanServiceChainUtils.java +++ b/vpnservice/cloud-servicechain/cloud-servicechain-impl/src/main/java/org/opendaylight/netvirt/cloudservicechain/utils/ElanServiceChainUtils.java @@ -83,20 +83,16 @@ public class ElanServiceChainUtils { 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) { @@ -128,42 +124,44 @@ public class ElanServiceChainUtils { } } - /* 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 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 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) @@ -173,7 +171,8 @@ public class ElanServiceChainUtils { } - /* 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 @@ -181,14 +180,14 @@ public class ElanServiceChainUtils { * 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) { @@ -214,14 +213,16 @@ public class ElanServiceChainUtils { * 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 buildSetLportTagAndGotoLportDispInstructions(long lportTag) { int instructionKey = 0; + BigInteger metadata = MetaDataUtil.getMetaDataForLPortDispatcher((int) lportTag, + NwConstants.SCF_SERVICE_INDEX); List result = - Arrays.asList(MDSALUtil.buildAndGetWriteMetadaInstruction(MetaDataUtil.getLportTagMetaData((int) lportTag), + Arrays.asList(MDSALUtil.buildAndGetWriteMetadaInstruction(metadata, MetaDataUtil.getMetaDataMaskForLPortDispatcher(), ++instructionKey), MDSALUtil.buildAndGetGotoTableInstruction(NwConstants.L3_INTERFACE_TABLE, ++instructionKey)); @@ -246,11 +247,11 @@ public class ElanServiceChainUtils { /** * 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) { @@ -273,9 +274,10 @@ public class ElanServiceChainUtils { /** * 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 getElanToLportTagList(final DataBroker broker, final String elanInstanceName) { ElanToPseudoPortDataKey key = new ElanToPseudoPortDataKey(elanInstanceName); diff --git a/vpnservice/cloud-servicechain/cloud-servicechain-impl/src/main/java/org/opendaylight/netvirt/cloudservicechain/utils/VpnServiceChainUtils.java b/vpnservice/cloud-servicechain/cloud-servicechain-impl/src/main/java/org/opendaylight/netvirt/cloudservicechain/utils/VpnServiceChainUtils.java index f6dba1d553..a725f94c4e 100644 --- a/vpnservice/cloud-servicechain/cloud-servicechain-impl/src/main/java/org/opendaylight/netvirt/cloudservicechain/utils/VpnServiceChainUtils.java +++ b/vpnservice/cloud-servicechain/cloud-servicechain-impl/src/main/java/org/opendaylight/netvirt/cloudservicechain/utils/VpnServiceChainUtils.java @@ -433,9 +433,16 @@ public class VpnServiceChainUtils { if ( addOrRemove == NwConstants.ADD_FLOW ) { VpnToPseudoPortTag newValue = new VpnToPseudoPortTagBuilder().setKey(key).setVrfId(rd).setLportTag((long) lportTag).build(); + logger.debug("Adding lportTag={} to VpnToLportTag map for VPN with rd={}", lportTag, rd); MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, path, newValue); } else { - MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, path); + logger.debug("Removing VpnToLportTag map entry for VPN with rd={}", rd); + try { + MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, path); + } catch ( Exception e ) { + // It may throw Exception if 'path' does not exist, but we dont care + logger.debug("Error when removing {}", path, e); + } } } diff --git a/vpnservice/fibmanager/fibmanager-impl/src/main/java/org/opendaylight/netvirt/fibmanager/VrfEntryListener.java b/vpnservice/fibmanager/fibmanager-impl/src/main/java/org/opendaylight/netvirt/fibmanager/VrfEntryListener.java index 80f256701b..44ed2aba84 100644 --- a/vpnservice/fibmanager/fibmanager-impl/src/main/java/org/opendaylight/netvirt/fibmanager/VrfEntryListener.java +++ b/vpnservice/fibmanager/fibmanager-impl/src/main/java/org/opendaylight/netvirt/fibmanager/VrfEntryListener.java @@ -574,7 +574,7 @@ public class VrfEntryListener extends AbstractDataChangeListener imple List targetDpns = ( vpnIs1stEndpoint ) ? vpnLinkState.get().getFirstEndpointState().getDpId() : vpnLinkState.get().getSecondEndpointState().getDpId(); - int lportTag = + Long lportTag = ( vpnIs1stEndpoint ) ? vpnLinkState.get().getSecondEndpointState().getLportTag() : vpnLinkState.get().getFirstEndpointState().getLportTag(); @@ -582,7 +582,7 @@ public class VrfEntryListener extends AbstractDataChangeListener imple List actionsInfos = Arrays.asList(new ActionInfo(ActionType.pop_mpls, new String[]{})); BigInteger[] metadata = new BigInteger[] { - MetaDataUtil.getMetaDataForLPortDispatcher(lportTag, ServiceIndex.getIndex(NwConstants.L3VPN_SERVICE_NAME, NwConstants.L3VPN_SERVICE_INDEX)), + MetaDataUtil.getMetaDataForLPortDispatcher(lportTag.intValue(), ServiceIndex.getIndex(NwConstants.L3VPN_SERVICE_NAME, NwConstants.L3VPN_SERVICE_INDEX)), MetaDataUtil.getMetaDataMaskForLPortDispatcher() }; List instructions = @@ -636,12 +636,12 @@ public class VrfEntryListener extends AbstractDataChangeListener imple vpnIsFirstEndpoint ? interVpnLinkState.get().getFirstEndpointState().getDpId() : interVpnLinkState.get().getSecondEndpointState().getDpId(); - Integer otherEndpointlportTag = + Long otherEndpointlportTag = vpnIsFirstEndpoint ? interVpnLinkState.get().getSecondEndpointState().getLportTag() : interVpnLinkState.get().getFirstEndpointState().getLportTag(); BigInteger[] metadata = new BigInteger[] { - MetaDataUtil.getMetaDataForLPortDispatcher(otherEndpointlportTag, + MetaDataUtil.getMetaDataForLPortDispatcher(otherEndpointlportTag.intValue(), ServiceIndex.getIndex(NwConstants.L3VPN_SERVICE_NAME, NwConstants.L3VPN_SERVICE_INDEX)), MetaDataUtil.getMetaDataMaskForLPortDispatcher() }; diff --git a/vpnservice/vpnmanager/vpnmanager-api/src/main/yang/inter-vpn-link.yang b/vpnservice/vpnmanager/vpnmanager-api/src/main/yang/inter-vpn-link.yang index ffb32a781d..14a6b0506c 100644 --- a/vpnservice/vpnmanager/vpnmanager-api/src/main/yang/inter-vpn-link.yang +++ b/vpnservice/vpnmanager/vpnmanager-api/src/main/yang/inter-vpn-link.yang @@ -45,7 +45,7 @@ module inter-vpn-link { } leaf lport-tag { - type uint16; + type uint32; } } diff --git a/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnConstants.java b/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnConstants.java index e63dbb33cd..237659c711 100644 --- a/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnConstants.java +++ b/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnConstants.java @@ -26,12 +26,11 @@ public class VpnConstants { public static final int ELAN_GID_MIN = 200000; // An IdPool for Pseudo LPort tags, that is, lportTags that are no related to an interface. - // These lportTags must be higher than 65535 to avoid collision with interface LportTags - // TODO: This pool details and creation... should it be located in InterfaceManager? - public static final String PSEUDO_LPORT_TAG_ID_POOL_NAME = System.getProperty("lporttag.idpool.name", "lporttag"); - public static final long LOWER_PSEUDO_LPORT_TAG = Long.getLong("lporttag.range.lower", 170001); - // The max value for LPortTag is 1F FF FF => 2097151 - public static final long UPPER_PSEUDO_LPORT_TAG = Long.getLong("lporttag.range.upper", 2097151); + // These lportTags must be higher than 170000 to avoid collision with interface LportTags and + // also VPN related IDs (vrfTags and labels) + public static final String PSEUDO_LPORT_TAG_ID_POOL_NAME = System.getProperty("lport.gid.name", "lporttag"); + public static final long LOWER_PSEUDO_LPORT_TAG = Long.getLong("lower.lport.gid", 170001); + public static final long UPPER_PSEUDO_LPORT_TAG = Long.getLong("upper.lport.gid", 270000); public static byte[] EthernetDestination_Broadcast = new byte[] { (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF }; diff --git a/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnRpcServiceImpl.java b/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnRpcServiceImpl.java index 2a17909dd7..44cb63717b 100644 --- a/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnRpcServiceImpl.java +++ b/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnRpcServiceImpl.java @@ -31,7 +31,7 @@ public class VpnRpcServiceImpl implements VpnRpcService { private final DataBroker dataBroker; private final IdManagerService idManager; private final VpnInterfaceManager vpnInterfaceMgr; - private final IFibManager fibManager; + private IFibManager fibManager; public VpnRpcServiceImpl(final DataBroker dataBroker, final IdManagerService idManager, final VpnInterfaceManager vpnIfaceMgr, final IFibManager fibManager) { @@ -41,6 +41,11 @@ public class VpnRpcServiceImpl implements VpnRpcService { this.fibManager = fibManager; } + public void setFibManager(IFibManager fibMgr) { + this.fibManager = fibMgr; + } + + /** * to generate label for the given ip prefix from the associated VPN * diff --git a/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnUtil.java b/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnUtil.java index 9b6c282bd5..324e89ce64 100644 --- a/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnUtil.java +++ b/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnUtil.java @@ -274,7 +274,7 @@ public class VpnUtil { } //FIXME: Implement caches for DS reads - static VpnInstance getVpnInstance(DataBroker broker, String vpnInstanceName) { + public static VpnInstance getVpnInstance(DataBroker broker, String vpnInstanceName) { InstanceIdentifier id = InstanceIdentifier.builder(VpnInstances.class).child(VpnInstance.class, new VpnInstanceKey(vpnInstanceName)).build(); Optional vpnInstance = read(broker, LogicalDatastoreType.CONFIGURATION, id); diff --git a/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/intervpnlink/InterVpnLinkListener.java b/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/intervpnlink/InterVpnLinkListener.java index 38d3de3dd9..60f17bf2cf 100644 --- a/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/intervpnlink/InterVpnLinkListener.java +++ b/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/intervpnlink/InterVpnLinkListener.java @@ -71,7 +71,7 @@ public class InterVpnLinkListener extends AbstractDataChangeListener 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 vpnLinkStateIid = VpnUtil.getInterVpnLinkStateIid(add.getName()); @@ -120,19 +124,29 @@ public class InterVpnLinkListener extends AbstractDataChangeListener secondDpnList = VpnUtil.pickRandomDPNs(dataBroker, numberOfDpns, firstDpnList); List 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(); @@ -174,8 +188,8 @@ public class InterVpnLinkListener extends AbstractDataChangeListener 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 @@ -289,6 +301,7 @@ public class InterVpnLinkListener extends AbstractDataChangeListener 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 @@ -296,46 +309,27 @@ public class InterVpnLinkListener extends AbstractDataChangeListener interVpnLinkStateIid = VpnUtil.getInterVpnLinkStateIid(del.getName()); VpnUtil.delete(dataBroker, LogicalDatastoreType.CONFIGURATION, interVpnLinkStateIid); } + private void removeVpnLinkEndpointFlows( String interVpnLinkName, String rd, String vpnUuid, List 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(); @@ -373,24 +396,15 @@ public class InterVpnLinkListener extends AbstractDataChangeListener> result = idManager.allocateId(getIdInput); RpcResult 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()); } @@ -412,6 +426,7 @@ public class InterVpnLinkListener extends AbstractDataChangeListener 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) diff --git a/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/intervpnlink/InterVpnLinkUtil.java b/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/intervpnlink/InterVpnLinkUtil.java index 6a6db38c3e..711bb463eb 100644 --- a/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/intervpnlink/InterVpnLinkUtil.java +++ b/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/intervpnlink/InterVpnLinkUtil.java @@ -121,11 +121,12 @@ public class InterVpnLinkUtil { */ public static void installLPortDispatcherTableFlow(DataBroker broker, IMdsalApiManager mdsalManager, InterVpnLink interVpnLink, List dpnList, - Uuid vpnUuidOtherEndpoint, Integer lPortTagOfOtherEndpoint) { + Uuid vpnUuidOtherEndpoint, Long lPortTagOfOtherEndpoint) { long vpnId = VpnUtil.getVpnId(broker, vpnUuidOtherEndpoint.getValue()); for ( BigInteger dpnId : dpnList ) { // insert into LPortDispatcher table - Flow lPortDispatcherFlow = buildLPortDispatcherFlow(interVpnLink.getName(), vpnId, lPortTagOfOtherEndpoint); + Flow lPortDispatcherFlow = buildLPortDispatcherFlow(interVpnLink.getName(), vpnId, + lPortTagOfOtherEndpoint.intValue()); mdsalManager.installFlow(dpnId, lPortDispatcherFlow); } } @@ -139,7 +140,7 @@ public class InterVpnLinkUtil { * @param lportTag DataPlane identifier of the LogicalPort. * @return the Flow ready to be installed */ - public static Flow buildLPortDispatcherFlow(String interVpnLinkName, long vpnId, Integer lportTag) { + public static Flow buildLPortDispatcherFlow(String interVpnLinkName, long vpnId, int lportTag) { LOG.info("Inter-vpn-link : buildLPortDispatcherFlow. vpnId {} lportTag {} ", vpnId, lportTag); List matches = Arrays.asList(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {