X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=vpnmanager%2Fvpnmanager-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fvpnservice%2FVpnInterfaceManager.java;h=b33fea8d226418e66572bde08f04bed564c31d7a;hb=f30638fcc162d85f21f33cef401b4fb5da05caaf;hp=45a21744d21cc205ecb875b304cca06009c75628;hpb=5c227c8ca7856fd48c4381491c086516420bf08a;p=vpnservice.git diff --git a/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/VpnInterfaceManager.java b/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/VpnInterfaceManager.java index 45a21744..b33fea8d 100644 --- a/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/VpnInterfaceManager.java +++ b/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/VpnInterfaceManager.java @@ -17,7 +17,10 @@ import org.opendaylight.controller.md.sal.binding.api.*; import org.opendaylight.vpnservice.mdsalutil.*; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.PrefixToInterface; import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.adjacency.list.AdjacencyKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.prefix.to._interface.vpn.ids.Prefixes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry; import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList; import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnListBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfacesBuilder; @@ -41,7 +44,7 @@ import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.ArrayList; -import java.util.concurrent.Future; +import java.util.concurrent.*; import com.google.common.base.Optional; @@ -73,7 +76,9 @@ import org.slf4j.LoggerFactory; public class VpnInterfaceManager extends AbstractDataChangeListener implements AutoCloseable { private static final Logger LOG = LoggerFactory.getLogger(VpnInterfaceManager.class); - private ListenerRegistration listenerRegistration; + private ListenerRegistration listenerRegistration, opListenerRegistration; + private ConcurrentMap vpnIntfMap = new ConcurrentHashMap(); + private ExecutorService executorService = Executors.newSingleThreadExecutor(); private final DataBroker broker; private final IBgpManager bgpManager; private IFibManager fibManager; @@ -83,6 +88,7 @@ public class VpnInterfaceManager extends AbstractDataChangeListener identifier, final VpnInterface vpnInterface) { - LOG.trace("key: {} , value: {}", identifier, vpnInterface ); + LOG.trace("VPN Interface key: {} , value: {}", identifier, vpnInterface ); addInterface(identifier, vpnInterface); } private void addInterface(final InstanceIdentifier identifier, final VpnInterface vpnInterface) { - LOG.trace("Add event - key: {}, value: {}" ,identifier, vpnInterface ); + LOG.trace("VPN Interface add event - key: {}, value: {}" ,identifier, vpnInterface ); final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class, VpnInterfaceKey.class); String interfaceName = key.getName(); @@ -173,11 +184,13 @@ public class VpnInterfaceManager extends AbstractDataChangeListener instructions = new ArrayList(); instructions.add(MDSALUtil.buildAndGetWriteMetadaInstruction(BigInteger.valueOf(vpnId), MetaDataUtil.METADATA_MASK_VRFID, ++instructionKey)); - instructions.add(MDSALUtil.buildAndGetGotoTableInstruction(VpnConstants.FIB_TABLE, ++instructionKey)); + instructions.add(MDSALUtil.buildAndGetGotoTableInstruction(NwConstants.L3_FIB_TABLE, ++instructionKey)); BoundServices serviceInfo = @@ -221,11 +247,12 @@ public class VpnInterfaceManager extends AbstractDataChangeListener identifier, VpnInterface intf) { + private void processVpnInterfaceAdjacencies(BigInteger dpnId, final InstanceIdentifier identifier, VpnInterface intf) { String intfName = intf.getName(); synchronized (intfName) { @@ -240,7 +267,6 @@ public class VpnInterfaceManager extends AbstractDataChangeListener matches = new ArrayList(); BigInteger metadata = MetaDataUtil.getMetaDataForLPortDispatcher(lPortTag, ++sIndex, BigInteger.valueOf(vpnId)); BigInteger metadataMask = MetaDataUtil.getMetaDataMaskForLPortDispatcher(MetaDataUtil.METADATA_MASK_SERVICE_INDEX, @@ -304,11 +340,10 @@ public class VpnInterfaceManager extends AbstractDataChangeListener vpnInterfaces = new ArrayList<>(); @@ -423,13 +458,13 @@ public class VpnInterfaceManager extends AbstractDataChangeListener identifier = VpnUtil.getVpnInterfaceIdentifier(interfaceName); - removeAdjacenciesFromVpn(identifier, vpnInterface); - LOG.info("Unbinding vpn service from interface {} ", interfaceName); - unbindService(vpnName, interfaceName, lPortTag); - updateDpnDbs(vpnName, interfaceName, false); - VpnUtil.delete(broker, LogicalDatastoreType.OPERATIONAL, identifier, VpnUtil.DEFAULT_CALLBACK); + synchronized (interfaceName.intern()) { + removeAdjacenciesFromVpn(identifier, vpnInterface); + LOG.info("Unbinding vpn service from interface {} ", interfaceName); + unbindService(dpId, vpnName, interfaceName, lPortTag, isInterfaceStateDown); + + //wait till DCN for removal of vpn interface in operational DS arrives + Runnable notifyTask = new VpnNotifyTask(); + synchronized (interfaceName.intern()) { + vpnIntfMap.put(interfaceName, notifyTask); + synchronized (notifyTask) { + try { + notifyTask.wait(VpnConstants.WAIT_TIME_IN_MILLISECONDS); + } catch (InterruptedException e) { + } + } + } + + } } private void removeAdjacenciesFromVpn(final InstanceIdentifier identifier, VpnInterface intf) { @@ -459,11 +507,11 @@ public class VpnInterfaceManager extends AbstractDataChangeListener identifier, - VpnInterface original, VpnInterface update) { - LOG.trace("Update VPN Interface {} , original {}, update {}", - identifier, original, update); - String vpnName = original.getVpnInstanceName(); - - boolean vpnNameChanged = false; - String rd = getRouteDistinguisher(vpnName); - String newRd = rd; - String newVpnName = update.getVpnInstanceName(); - if(!vpnName.equals(newVpnName)) { - //VPN for this interface got changed. - //Remove the interface from old VPN and add it to new VPN - newRd = getRouteDistinguisher(newVpnName); - if(newRd.equals("")) { - LOG.warn("VPN Instance {} not found. Update operation aborted", newVpnName); - return; - } - vpnNameChanged = true; - LOG.debug("New VPN Name for the interface {} is {}", newVpnName, original.getName()); + protected void update(InstanceIdentifier identifier, VpnInterface original, VpnInterface update) { + if (LOG.isTraceEnabled()) { + LOG.trace("Updating VPN Interface : key " + identifier + ", original value=" + original + ", update " + + "value=" + update); } - + String oldVpnName = original.getVpnInstanceName(); + String newVpnName = update.getVpnInstanceName(); List oldAdjs = original.getAugmentation(Adjacencies.class).getAdjacency(); List newAdjs = update.getAugmentation(Adjacencies.class).getAdjacency(); - if(vpnNameChanged && newAdjs != null && !newAdjs.isEmpty()) { - long label = VpnConstants.INVALID_ID; - InstanceIdentifier path = identifier.augmentation(Adjacencies.class); - Optional adjacencies = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, path); - if (adjacencies.isPresent()) { - List nextHops = adjacencies.get().getAdjacency(); - for(Adjacency nextHop : nextHops) { - label = nextHop.getLabel(); - if(label == VpnConstants.INVALID_ID) { - //Generate label using ID Manager - label = VpnUtil.getUniqueId(idManager, VpnConstants.VPN_IDPOOL_NAME, - VpnUtil.getNextHopLabelKey(newRd, nextHop.getIpAddress())); - } - if (rd != null) { - removePrefixFromBGP(rd, nextHop.getIpAddress()); - } else { - removeFibEntryFromDS(vpnName, nextHop.getIpAddress()); - } - //updatePrefixToBGP(newRd, nextHop, nextHopIp, label); - } - processVpnInterfaceAdjacencies(identifier, update); - VpnUtil.syncUpdate(broker, LogicalDatastoreType.OPERATIONAL, identifier, update); - } - } else if (oldAdjs != newAdjs) { - //handle both addition and removal of adjacencies - //currently, new adjacency may be an extra route + if (oldAdjs == null) { + oldAdjs = new ArrayList<>(); + } + if (newAdjs == null) { + newAdjs = new ArrayList<>(); + } + //handles switching between + if (!oldVpnName.equals(newVpnName)) { + remove(identifier, original); + add(identifier, update); + } + //handle both addition and removal of adjacencies + //currently, new adjacency may be an extra route + if (!oldAdjs.equals(newAdjs)) { for (Adjacency adj : newAdjs) { if (oldAdjs.contains(adj)) { oldAdjs.remove(adj); @@ -554,15 +579,10 @@ public class VpnInterfaceManager extends AbstractDataChangeListener idBuilder = InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd)).child(VrfEntry.class, new VrfEntryKey(prefix)); InstanceIdentifier vrfEntryId = idBuilder.build(); - VpnUtil.delete(broker, LogicalDatastoreType.OPERATIONAL, vrfEntryId, VpnUtil.DEFAULT_CALLBACK); + VpnUtil.delete(broker, LogicalDatastoreType.CONFIGURATION, vrfEntryId, VpnUtil.DEFAULT_CALLBACK); } @@ -640,7 +660,7 @@ public class VpnInterfaceManager extends AbstractDataChangeListener vrfTableId = idBuilder.build(); - VpnUtil.delete(broker, LogicalDatastoreType.OPERATIONAL, vrfTableId, VpnUtil.DEFAULT_CALLBACK); + VpnUtil.delete(broker, LogicalDatastoreType.CONFIGURATION, vrfTableId, VpnUtil.DEFAULT_CALLBACK); } @@ -673,7 +693,7 @@ public class VpnInterfaceManager extends AbstractDataChangeListener { + + public VpnInterfaceOpListener() { + super(VpnInterface.class); + } + + @Override + protected void remove(InstanceIdentifier identifier, VpnInterface del) { + final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class, VpnInterfaceKey.class); + String interfaceName = key.getName(); + + //increment the vpn interface count in Vpn Instance Op Data + Long ifCnt = 0L; + String rd = getRouteDistinguisher(del.getVpnInstanceName()); + if(rd == null || rd.isEmpty()) rd = del.getVpnInstanceName(); + VpnInstanceOpDataEntry vpnInstOp = VpnUtil.getVpnInstanceOpData(broker, rd); + if(vpnInstOp != null && vpnInstOp.getVpnInterfaceCount() != null) { + ifCnt = vpnInstOp.getVpnInterfaceCount(); + } + + LOG.trace("VpnInterfaceOpListener remove: interface name {} rd {} interface count in Vpn Op Instance {}", interfaceName, rd, ifCnt); + + if(ifCnt != 0) { + VpnUtil.asyncUpdate(broker, LogicalDatastoreType.OPERATIONAL, + VpnUtil.getVpnInstanceOpDataIdentifier(rd), + VpnUtil.updateIntfCntInVpnInstOpData(ifCnt - 1, rd), VpnUtil.DEFAULT_CALLBACK); + } + + // Vpn Interface removed => No more adjacencies from it. + // Hence clean up interface from vpn-dpn-interface list. + Adjacency adjacency = del.getAugmentation(Adjacencies.class).getAdjacency().get(0); + Optional prefixToInterface = Optional.absent(); + prefixToInterface = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, + VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(), + VpnUtil.getIpPrefix(adjacency.getIpAddress()))); + if (!prefixToInterface.isPresent()) { + prefixToInterface = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, + VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(), + VpnUtil.getIpPrefix(adjacency.getNextHopIp()))); + } + if (prefixToInterface.isPresent()) { + VpnUtil.delete(broker, LogicalDatastoreType.OPERATIONAL, + VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(), + prefixToInterface.get().getIpAddress()), + VpnUtil.DEFAULT_CALLBACK); + updateDpnDbs(prefixToInterface.get().getDpnId(), del.getVpnInstanceName(), interfaceName, false); + } + notifyTaskIfRequired(interfaceName); + } + + private void notifyTaskIfRequired(String intfName) { + Runnable notifyTask = vpnIntfMap.remove(intfName); + if (notifyTask == null) { + return; + } + executorService.execute(notifyTask); + } + + @Override + protected void update(InstanceIdentifier identifier, VpnInterface original, VpnInterface update) { + } + + @Override + protected void add(InstanceIdentifier identifier, VpnInterface add) { + final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class, VpnInterfaceKey.class); + String interfaceName = key.getName(); + + //increment the vpn interface count in Vpn Instance Op Data + Long ifCnt = 0L; + String rd = getRouteDistinguisher(add.getVpnInstanceName()); + if(rd == null || rd.isEmpty()) rd = add.getVpnInstanceName(); + VpnInstanceOpDataEntry vpnInstOp = VpnUtil.getVpnInstanceOpData(broker, rd); + if(vpnInstOp != null && vpnInstOp.getVpnInterfaceCount() != null) { + ifCnt = vpnInstOp.getVpnInterfaceCount(); + } + + LOG.trace("VpnInterfaceOpListener add: interface name {} rd {} interface count in Vpn Op Instance {}", interfaceName, rd, ifCnt); + + VpnUtil.asyncUpdate(broker, LogicalDatastoreType.OPERATIONAL, + VpnUtil.getVpnInstanceOpDataIdentifier(rd), + VpnUtil.updateIntfCntInVpnInstOpData(ifCnt + 1, rd), VpnUtil.DEFAULT_CALLBACK); + + + } + } + protected void updatePrefixesForDPN(BigInteger dpnId, UpdateRouteAction action) { + LOG.info("Tunnel event triggered {} for Dpn:{} ", action.name(), dpnId); InstanceIdentifierBuilder idBuilder = InstanceIdentifier.builder(VpnInstances.class); InstanceIdentifier vpnInstancesId = idBuilder.build(); Optional vpnInstances = VpnUtil.read(broker, LogicalDatastoreType.CONFIGURATION, vpnInstancesId); @@ -746,46 +873,60 @@ public class VpnInterfaceManager extends AbstractDataChangeListener vpnInstIter = vpnInstanceList.iterator(); while (vpnInstIter.hasNext()) { VpnInstance vpnInstance = vpnInstIter.next(); - VpnAfConfig vpnConfig = vpnInstance.getIpv4Family(); - String rd = vpnConfig.getRouteDistinguisher(); - - InstanceIdentifier id = VpnUtil.getVpnToDpnListIdentifier(rd, dpnId); - Optional dpnInVpn = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, id); - if (dpnInVpn.isPresent()) { - if (action == UpdateRouteAction.ADVERTISE_ROUTE) { - fibManager.populateFibOnNewDpn(dpnId, VpnUtil - .getVpnId(broker, vpnInstance.getVpnInstanceName()), rd); + try { + VpnAfConfig vpnConfig = vpnInstance.getIpv4Family(); + String rd = vpnConfig.getRouteDistinguisher(); + if (rd == null || rd.isEmpty()) { + rd = vpnInstance.getVpnInstanceName(); } - List vpnInterfaces = dpnInVpn.get().getVpnInterfaces(); - for(org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data - .vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces vpnInterface : vpnInterfaces) { - InstanceIdentifier vpnIntfId = VpnUtil.getVpnInterfaceIdentifier(vpnInterface.getInterfaceName()); - InstanceIdentifier path = vpnIntfId.augmentation(Adjacencies.class); - Optional adjacencies = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, path); - - if (adjacencies.isPresent()) { - List adjacencyList = adjacencies.get().getAdjacency(); - Iterator adjacencyIterator = adjacencyList.iterator(); - - while (adjacencyIterator.hasNext()) { - Adjacency adjacency = adjacencyIterator.next(); - try { - if(action == UpdateRouteAction.ADVERTISE_ROUTE) - bgpManager.addPrefix(rd, adjacency.getIpAddress(), adjacency.getNextHopIp(), adjacency.getLabel().intValue()); - else if(action == UpdateRouteAction.WITHDRAW_ROUTE) - bgpManager.deletePrefix(rd, adjacency.getIpAddress()); - } catch (Exception e) { - LOG.error("Exception when updating prefix {} in vrf {} to BGP", adjacency.getIpAddress(), rd); + InstanceIdentifier id = + VpnUtil.getVpnToDpnListIdentifier(rd, dpnId); + Optional dpnInVpn = + VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, id); + if (dpnInVpn.isPresent()) { + // if (action == UpdateRouteAction.ADVERTISE_ROUTE) { + // fibManager.populateFibOnNewDpn(dpnId, VpnUtil + // .getVpnId(broker, vpnInstance.getVpnInstanceName()), rd); + // } + List + vpnInterfaces = dpnInVpn.get().getVpnInterfaces(); + for (org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data + .vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces vpnInterface : vpnInterfaces) { + InstanceIdentifier vpnIntfId = + VpnUtil.getVpnInterfaceIdentifier(vpnInterface.getInterfaceName()); + InstanceIdentifier path = + vpnIntfId.augmentation(Adjacencies.class); + Optional adjacencies = + VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, path); + + if (adjacencies.isPresent()) { + List adjacencyList = adjacencies.get().getAdjacency(); + Iterator adjacencyIterator = adjacencyList.iterator(); + + while (adjacencyIterator.hasNext()) { + Adjacency adjacency = adjacencyIterator.next(); + try { + if (action == UpdateRouteAction.ADVERTISE_ROUTE) + bgpManager.addPrefix(rd, adjacency.getIpAddress(), + adjacency.getNextHopIp(), + adjacency.getLabel().intValue()); + else if (action == UpdateRouteAction.WITHDRAW_ROUTE) + bgpManager.deletePrefix(rd, adjacency.getIpAddress()); + } catch (Exception e) { + LOG.error("Exception when updating prefix {} in vrf {} to BGP", + adjacency.getIpAddress(), rd); + } } } - } + } + // if (action == UpdateRouteAction.WITHDRAW_ROUTE) { + // fibManager.cleanUpDpnForVpn(dpnId, VpnUtil.getVpnId(broker, vpnInstance.getVpnInstanceName()), rd); + // } } - if (action == UpdateRouteAction.WITHDRAW_ROUTE) { - fibManager.cleanUpDpnForVpn(dpnId, VpnUtil - .getVpnId(broker, vpnInstance.getVpnInstanceName()), rd); - } + } catch (Exception e) { + LOG.error("updatePrefixesForDPN {} in vpn {} failed", dpnId, vpnInstance.getVpnInstanceName(), e); } } }