X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=fibmanager%2Ffibmanager-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fvpnservice%2Ffibmanager%2FFibManager.java;h=128444c65991b8f57dbcb88593d7c75afda3587e;hb=f30638fcc162d85f21f33cef401b4fb5da05caaf;hp=7adde2c47d7fb3d6dae78c6b9ba79bd96f774747;hpb=acac66d2b4b29eab99b2604965680f50da9eb9ef;p=vpnservice.git diff --git a/fibmanager/fibmanager-impl/src/main/java/org/opendaylight/vpnservice/fibmanager/FibManager.java b/fibmanager/fibmanager-impl/src/main/java/org/opendaylight/vpnservice/fibmanager/FibManager.java index 7adde2c4..128444c6 100644 --- a/fibmanager/fibmanager-impl/src/main/java/org/opendaylight/vpnservice/fibmanager/FibManager.java +++ b/fibmanager/fibmanager-impl/src/main/java/org/opendaylight/vpnservice/fibmanager/FibManager.java @@ -43,6 +43,7 @@ import org.opendaylight.vpnservice.mdsalutil.NwConstants; import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager; import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.PrefixToInterface; import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.VpnInstanceOpData; +import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.VpnToExtraroute; import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.prefix.to._interface.VpnIds; import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.prefix.to._interface.VpnIdsKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.prefix.to._interface.vpn.ids.Prefixes; @@ -52,6 +53,11 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instanc 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.params.xml.ns.yang.overlay.rev150105.TunnelTypeVxlan; import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.ItmRpcService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.to.extraroute.Vpn; +import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.to.extraroute.VpnKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.to.extraroute.vpn.Extraroute; +import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.to.extraroute.vpn.ExtrarouteBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.to.extraroute.vpn.ExtrarouteKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.fibmanager.rev150330.FibEntries; import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.fibmanager.rev150330.fibentries.VrfTables; import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.fibmanager.rev150330.fibentries.VrfTablesKey; @@ -64,6 +70,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpc import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetTunnelTypeOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.OdlInterfaceRpcService; import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.l3nexthop.rev150409.l3nexthop.vpnnexthops.VpnNexthop; +import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.Adjacencies; import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; @@ -90,17 +97,6 @@ public class FibManager extends AbstractDataChangeListener implements public static final BigInteger COOKIE_TUNNEL = new BigInteger("9000000", 16); - private static final FutureCallback DEFAULT_CALLBACK = - new FutureCallback() { - public void onSuccess(Void result) { - LOG.debug("Success in Datastore write operation"); - } - - public void onFailure(Throwable error) { - LOG.error("Error in Datastore write operation", error); - }; - }; - public FibManager(final DataBroker db) { super(VrfEntry.class); broker = db; @@ -142,7 +138,7 @@ public class FibManager extends AbstractDataChangeListener implements private void registerListener(final DataBroker db) { try { - listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL, + listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION, getWildCardPath(), FibManager.this, DataChangeScope.SUBTREE); } catch (final Exception e) { LOG.error("FibManager DataChange listener registration fail!", e); @@ -150,31 +146,11 @@ public class FibManager extends AbstractDataChangeListener implements } } - private Optional read(LogicalDatastoreType datastoreType, - InstanceIdentifier path) { - - ReadOnlyTransaction tx = broker.newReadOnlyTransaction(); - - Optional result = Optional.absent(); - try { - result = tx.read(datastoreType, path).get(); - } catch (Exception e) { - throw new RuntimeException(e); - } - - return result; - } private InstanceIdentifier getWildCardPath() { return InstanceIdentifier.create(FibEntries.class).child(VrfTables.class).child(VrfEntry.class); } - private void asyncWrite(LogicalDatastoreType datastoreType, - InstanceIdentifier path, T data, FutureCallback callback) { - WriteTransaction tx = broker.newWriteOnlyTransaction(); - tx.put(datastoreType, path, data, true); - Futures.addCallback(tx.submit(), callback); - } @Override protected void add(final InstanceIdentifier identifier, @@ -221,18 +197,20 @@ public class FibManager extends AbstractDataChangeListener implements public BigInteger createLocalFibEntry(Long vpnId, String rd, VrfEntry vrfEntry) { BigInteger localDpnId = BigInteger.ZERO; Prefixes localNextHopInfo = getPrefixToInterface(vpnId, vrfEntry.getDestPrefix()); - boolean staticRoute = false; + String localNextHopIP = vrfEntry.getDestPrefix(); - //If the vrf entry is a static/extra route, the nexthop of the entry would be a adjacency in the vpn if(localNextHopInfo == null) { - localNextHopInfo = getPrefixToInterface(vpnId, vrfEntry.getNextHopAddress() + "/32"); - staticRoute = true; + //Is this fib route an extra route? If yes, get the nexthop which would be an adjacency in the vpn + Extraroute extra_route = getVpnToExtraroute(rd, vrfEntry.getDestPrefix()); + if (extra_route != null) { + localNextHopInfo = getPrefixToInterface(vpnId, extra_route.getNexthopIp() + "/32"); + localNextHopIP = extra_route.getNexthopIp() + "/32"; + } } if(localNextHopInfo != null) { localDpnId = localNextHopInfo.getDpnId(); - long groupId = nextHopManager.createLocalNextHop(vpnId, localDpnId, localNextHopInfo.getVpnInterfaceName(), - (staticRoute == true) ? vrfEntry.getNextHopAddress() + "/32" : vrfEntry.getDestPrefix()); + long groupId = nextHopManager.createLocalNextHop(vpnId, localDpnId, localNextHopInfo.getVpnInterfaceName(), localNextHopIP); List actionInfos = new ArrayList(); actionInfos.add(new ActionInfo(ActionType.group, new String[] { String.valueOf(groupId)})); @@ -283,9 +261,7 @@ public class FibManager extends AbstractDataChangeListener implements LOG.info("remove terminatingServiceActions called with DpnId = {} and label = {}", dpId , label); List mkMatches = new ArrayList(); // Matching metadata - mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[] { - MetaDataUtil.getTunnelIdWithValidVniBitAndVniSet((int)label), - MetaDataUtil.METADA_MASK_TUNNEL_ID })); + mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[] {BigInteger.valueOf(label)})); flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INTERNAL_TUNNEL_TABLE, getFlowRef(dpId, NwConstants.INTERNAL_TUNNEL_TABLE, (int)label), @@ -297,25 +273,30 @@ public class FibManager extends AbstractDataChangeListener implements public BigInteger deleteLocalFibEntry(Long vpnId, String rd, VrfEntry vrfEntry) { BigInteger localDpnId = BigInteger.ZERO; + boolean isExtraRoute = false; VpnNexthop localNextHopInfo = nextHopManager.getVpnNexthop(vpnId, vrfEntry.getDestPrefix()); - boolean staticRoute = false; + String localNextHopIP = vrfEntry.getDestPrefix(); - //If the vrf entry is a static/extra route, the nexthop of the entry would be a adjacency in the vpn if(localNextHopInfo == null) { - localNextHopInfo = nextHopManager.getVpnNexthop(vpnId, vrfEntry.getNextHopAddress() + "/32"); - staticRoute = true; + //Is this fib route an extra route? If yes, get the nexthop which would be an adjacency in the vpn + Extraroute extra_route = getVpnToExtraroute(rd, vrfEntry.getDestPrefix()); + if (extra_route != null) { + localNextHopInfo = nextHopManager.getVpnNexthop(vpnId, extra_route.getNexthopIp() + "/32"); + localNextHopIP = extra_route.getNexthopIp() + "/32"; + isExtraRoute = true; + } } + if(localNextHopInfo != null) { localDpnId = localNextHopInfo.getDpnId(); - if (getPrefixToInterface(vpnId, (staticRoute == true) ? vrfEntry.getNextHopAddress() + "/32" : vrfEntry.getDestPrefix()) == null) { + Prefixes prefix = getPrefixToInterface(vpnId, isExtraRoute ? localNextHopIP : vrfEntry.getDestPrefix()); makeConnectedRoute(localDpnId, vpnId, vrfEntry, rd, null /* invalid */, NwConstants.DEL_FLOW); makeLFibTableEntry(localDpnId, vrfEntry.getLabel(), 0 /* invalid */, vrfEntry.getNextHopAddress(), NwConstants.DEL_FLOW); removeTunnelTableEntry(localDpnId, vrfEntry.getLabel()); - deleteLocalAdjacency(localDpnId, vpnId, (staticRoute == true) ? vrfEntry.getNextHopAddress() + "/32" : vrfEntry.getDestPrefix()); - } + deleteLocalAdjacency(localDpnId, vpnId, localNextHopIP); } return localDpnId; } @@ -327,10 +308,22 @@ public class FibManager extends AbstractDataChangeListener implements private Prefixes getPrefixToInterface(Long vpnId, String ipPrefix) { Optional localNextHopInfoData = - read(LogicalDatastoreType.OPERATIONAL, getPrefixToInterfaceIdentifier(vpnId, ipPrefix)); + FibUtil.read(broker, LogicalDatastoreType.OPERATIONAL, getPrefixToInterfaceIdentifier(vpnId, ipPrefix)); return localNextHopInfoData.isPresent() ? localNextHopInfoData.get() : null; } - + + private InstanceIdentifier getVpnToExtrarouteIdentifier(String vrfId, String ipPrefix) { + return InstanceIdentifier.builder(VpnToExtraroute.class) + .child(Vpn.class, new VpnKey(vrfId)).child(Extraroute.class, + new ExtrarouteKey(ipPrefix)).build(); + } + + private Extraroute getVpnToExtraroute(String rd, String ipPrefix) { + Optional extraRouteInfo = + FibUtil.read(broker, LogicalDatastoreType.OPERATIONAL, getVpnToExtrarouteIdentifier(rd, ipPrefix)); + return extraRouteInfo.isPresent() ? extraRouteInfo.get() : null; + + } private Class getTunnelType(String ifName) { try { @@ -356,7 +349,7 @@ public class FibManager extends AbstractDataChangeListener implements String rd = vrfTableKey.getRouteDistinguisher(); LOG.debug("adding route " + vrfEntry.getDestPrefix() + " " + rd); /********************************************/ - String tunnelInterface = resolveAdjacency(localDpnId, remoteDpnId, vpnId, vrfEntry); + String tunnelInterface = resolveAdjacency(localDpnId, remoteDpnId, vpnId, vrfEntry, rd); if(tunnelInterface == null) { LOG.error("Could not get interface for nexthop: {} in vpn {}", vrfEntry.getNextHopAddress(), rd); @@ -416,6 +409,75 @@ public class FibManager extends AbstractDataChangeListener implements "Successfully added fib entry for " + vrfEntry.getDestPrefix() + " vpnId " + vpnId); } + private void delIntfFromDpnToVpnList(long vpnId, BigInteger dpnId, String intfName, String rd) { + InstanceIdentifier id = FibUtil.getVpnToDpnListIdentifier(rd, dpnId); + Optional dpnInVpn = FibUtil.read(broker, LogicalDatastoreType.OPERATIONAL, id); + if (dpnInVpn.isPresent()) { + List vpnInterfaces = dpnInVpn.get().getVpnInterfaces(); + org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces + currVpnInterface = new org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfacesBuilder().setInterfaceName(intfName).build(); + + if (vpnInterfaces.remove(currVpnInterface)) { + if (vpnInterfaces.isEmpty()) { + LOG.trace("Last vpn interface {} on dpn {} for vpn {}. Clean up fib in dpn", intfName, dpnId, rd); + FibUtil.delete(broker, LogicalDatastoreType.OPERATIONAL, id); + cleanUpDpnForVpn(dpnId, vpnId, rd); + } else { + LOG.trace("Delete vpn interface {} from dpn {} to vpn {} list.", intfName, dpnId, rd); + FibUtil.delete(broker, LogicalDatastoreType.OPERATIONAL, id.child( + org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data + .vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces.class, + new org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfacesKey(intfName))); + } + } + } + } + + private void cleanUpOpDataForFib(Long vpnId, String rd, final VrfEntry vrfEntry) { + /* Get interface info from prefix to interface mapping; + Use the interface info to get the corresponding vpn interface op DS entry, + remove the adjacency corresponding to this fib entry. + If adjacency removed is the last adjacency, clean up the following: + - vpn interface from dpntovpn list, dpn if last vpn interface on dpn + - prefix to interface entry + - vpn interface op DS + */ + Prefixes prefixInfo = getPrefixToInterface(vpnId, vrfEntry.getDestPrefix()); + Extraroute extraRoute = null; + if (prefixInfo == null) { + extraRoute = getVpnToExtraroute(rd, vrfEntry.getDestPrefix()); + if(extraRoute != null) { + prefixInfo = getPrefixToInterface(vpnId, extraRoute.getNexthopIp() + "/32"); + //clean up the vpn to extra route entry in DS + FibUtil.delete(broker, LogicalDatastoreType.OPERATIONAL, FibUtil.getVpnToExtrarouteIdentifier(rd, vrfEntry.getDestPrefix())); + } + } + if (prefixInfo == null) { + LOG.debug("Cleanup VPN Data Failed as unable to find prefix Info for " + vrfEntry.getDestPrefix()); + return; //Don't have any info for this prefix (shouldn't happen); need to return + } + String ifName = prefixInfo.getVpnInterfaceName(); + Optional optAdjacencies = FibUtil.read(broker, LogicalDatastoreType.OPERATIONAL, FibUtil.getAdjListPath(ifName)); + int numAdj = 0; + if (optAdjacencies.isPresent()) { + numAdj = optAdjacencies.get().getAdjacency().size(); + } + LOG.trace("cleanUpOpDataForFib: remove adjacency for prefix: {} {}", vpnId, vrfEntry.getDestPrefix()); + //remove adjacency corr to prefix + if (numAdj > 1) { + FibUtil.delete(broker, LogicalDatastoreType.OPERATIONAL, + FibUtil.getAdjacencyIdentifier(ifName, vrfEntry.getDestPrefix())); + } + + if ((numAdj - 1) == 0) { //there are no adjacencies left for this vpn interface, clean up + //clean up the vpn interface from DpnToVpn list + LOG.trace("Clean up vpn interface {} from dpn {} to vpn {} list.", ifName, prefixInfo.getDpnId(), rd); + FibUtil.delete(broker, LogicalDatastoreType.OPERATIONAL, + FibUtil.getVpnInterfaceIdentifier(ifName)); + } + } + private void deleteFibEntries(final InstanceIdentifier identifier, final VrfEntry vrfEntry) { final VrfTablesKey vrfTableKey = identifier.firstKeyOf(VrfTables.class, VrfTablesKey.class); @@ -433,8 +495,10 @@ public class FibManager extends AbstractDataChangeListener implements deleteRemoteRoute(localDpnId, curDpn.getDpnId(), vpnInstance.getVpnId(), vrfTableKey, vrfEntry); } } - } + //The flow/group entry has been deleted from config DS; need to clean up associated operational + //DS entries in VPN Op DS, VpnInstanceOpData and PrefixToInterface to complete deletion + cleanUpOpDataForFib(vpnInstance.getVpnId(), vrfTableKey.getRouteDistinguisher(), vrfEntry); } public void deleteRemoteRoute(final BigInteger localDpnId, final BigInteger remoteDpnId, @@ -442,17 +506,27 @@ public class FibManager extends AbstractDataChangeListener implements final VrfEntry vrfEntry) { LOG.debug("deleting route "+ vrfEntry.getDestPrefix() + " "+vpnId); String rd = vrfTableKey.getRouteDistinguisher(); - String egressInterface = resolveAdjacency(localDpnId, remoteDpnId, vpnId, vrfEntry); - if(egressInterface == null) { - LOG.error("Could not get nexthop group id for nexthop: {} in vpn {}", - vrfEntry.getNextHopAddress(), rd); - LOG.warn("Failed to delete Route: {} in vpn: {}", - vrfEntry.getDestPrefix(), rd); - return; + boolean isRemoteRoute = true; + if (localDpnId == null) { + // localDpnId is not known when clean up happens for last vm for a vpn on a dpn + VpnNexthop localNextHopInfo = nextHopManager.getVpnNexthop(vpnId, vrfEntry.getDestPrefix()); + if(localNextHopInfo == null) { + //Is this fib route an extra route? If yes, get the nexthop which would be an adjacency in the vpn + Extraroute extra_route = getVpnToExtraroute(rd, vrfEntry.getDestPrefix()); + if (extra_route != null) { + localNextHopInfo = nextHopManager.getVpnNexthop(vpnId, extra_route.getNexthopIp()); + } + } + if (localNextHopInfo != null) { + isRemoteRoute = (!remoteDpnId.equals(localNextHopInfo.getDpnId())); + } + } + if (isRemoteRoute) { + makeConnectedRoute(remoteDpnId, vpnId, vrfEntry, rd, null, NwConstants.DEL_FLOW); + LOG.debug("Successfully delete fib entry for "+ vrfEntry.getDestPrefix() + " vpnId "+vpnId); + } else{ + LOG.debug("Did not delete fib entry rd: {} =, prefix: {} as it is local to dpn {}", rd, vrfEntry.getDestPrefix(), remoteDpnId); } - - makeConnectedRoute(remoteDpnId, vpnId, vrfEntry, rd, null, NwConstants.DEL_FLOW); - LOG.debug("Successfully delete fib entry for "+ vrfEntry.getDestPrefix() + " vpnId "+vpnId); } private long getIpAddress(byte[] rawIpAddress) { @@ -508,13 +582,9 @@ public class FibManager extends AbstractDataChangeListener implements * for or for notification that operational DS write for flows is done. We do not turn on the stats writing for flows, * so that notification never comes, so we do not need that wait. Sending the lowest value of wait "1 ms" since 0 wait means * wait indefinitely. */ - // FIXME: sync calls. - //mdsalManager.syncInstallFlow(flowEntity, 1); - mdsalManager.installFlow(flowEntity); + mdsalManager.syncInstallFlow(flowEntity, 1); } else { - // FIXME: sync calls. - // mdsalManager.syncRemoveFlow(flowEntity, 1); - mdsalManager.removeFlow(flowEntity); + mdsalManager.syncRemoveFlow(flowEntity, 1); } } @@ -546,13 +616,9 @@ public class FibManager extends AbstractDataChangeListener implements * so that notification never comes, so we do not need that wait. Sending the lowest value of wait "1 ms" since 0 wait means * wait indefinitely. */ - // FIXME: - // mdsalManager.syncInstallFlow(flowEntity, 1); - mdsalManager.installFlow(flowEntity); + mdsalManager.syncInstallFlow(flowEntity, 1); } else { - // FIXME: - // mdsalManager.syncRemoveFlow(flowEntity, 1); - mdsalManager.removeFlow(flowEntity); + mdsalManager.syncRemoveFlow(flowEntity, 1); } LOG.debug("LFIB Entry for dpID {} : label : {} group {} modified successfully {}",dpId, label, groupId ); } @@ -569,12 +635,33 @@ public class FibManager extends AbstractDataChangeListener implements public void populateFibOnNewDpn(BigInteger dpnId, long vpnId, String rd) { LOG.trace("New dpn {} for vpn {} : populateFibOnNewDpn", dpnId, rd); InstanceIdentifier id = buildVrfId(rd); - Optional vrfTable = read(LogicalDatastoreType.OPERATIONAL, id); - if(vrfTable.isPresent()) { - for(VrfEntry vrfEntry : vrfTable.get().getVrfEntry()) { - // Passing null as we don't know the dpn - // to which prefix is attached at this point - createRemoteFibEntry(null, dpnId, vpnId, vrfTable.get().getKey(), vrfEntry); + String lockOnDpnVpn = new String(dpnId.toString()+ vpnId); + synchronized (lockOnDpnVpn.intern()) { + Optional vrfTable = FibUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id); + if (vrfTable.isPresent()) { + for (VrfEntry vrfEntry : vrfTable.get().getVrfEntry()) { + // Passing null as we don't know the dpn + // to which prefix is attached at this point + createRemoteFibEntry(null, dpnId, vpnId, vrfTable.get().getKey(), vrfEntry); + } + } + } + } + + public void populateFibOnDpn(BigInteger dpnId, long vpnId, String rd, String nexthopIp) { + LOG.trace("dpn {} for vpn {}, nexthopIp {} : populateFibOnDpn", dpnId, rd, nexthopIp); + InstanceIdentifier id = buildVrfId(rd); + String lockOnDpnVpn = new String(dpnId.toString()+ vpnId); + synchronized (lockOnDpnVpn.intern()) { + Optional vrfTable = FibUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id); + if (vrfTable.isPresent()) { + for (VrfEntry vrfEntry : vrfTable.get().getVrfEntry()) { + // Passing null as we don't know the dpn + // to which prefix is attached at this point + if (nexthopIp == vrfEntry.getNextHopAddress()) { + createRemoteFibEntry(null, dpnId, vpnId, vrfTable.get().getKey(), vrfEntry); + } + } } } } @@ -582,12 +669,33 @@ public class FibManager extends AbstractDataChangeListener implements public void cleanUpDpnForVpn(BigInteger dpnId, long vpnId, String rd) { LOG.trace("Remove dpn {} for vpn {} : cleanUpDpnForVpn", dpnId, rd); InstanceIdentifier id = buildVrfId(rd); - Optional vrfTable = read(LogicalDatastoreType.OPERATIONAL, id); - if(vrfTable.isPresent()) { - for(VrfEntry vrfEntry : vrfTable.get().getVrfEntry()) { - // Passing null as we don't know the dpn - // to which prefix is attached at this point - deleteRemoteRoute(null, dpnId, vpnId, vrfTable.get().getKey(), vrfEntry); + String lockOnDpnVpn = new String(dpnId.toString()+ vpnId); + synchronized (lockOnDpnVpn.intern()) { + Optional vrfTable = FibUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id); + if (vrfTable.isPresent()) { + for (VrfEntry vrfEntry : vrfTable.get().getVrfEntry()) { + // Passing null as we don't know the dpn + // to which prefix is attached at this point + deleteRemoteRoute(null, dpnId, vpnId, vrfTable.get().getKey(), vrfEntry); + } + } + } + } + + public void cleanUpDpnForVpn(BigInteger dpnId, long vpnId, String rd, String nexthopIp) { + LOG.trace("dpn {} for vpn {}, nexthopIp {} : cleanUpDpnForVpn", dpnId, rd, nexthopIp); + InstanceIdentifier id = buildVrfId(rd); + String lockOnDpnVpn = new String(dpnId.toString()+ vpnId); + synchronized (lockOnDpnVpn.intern()) { + Optional vrfTable = FibUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id); + if (vrfTable.isPresent()) { + for (VrfEntry vrfEntry : vrfTable.get().getVrfEntry()) { + // Passing null as we don't know the dpn + // to which prefix is attached at this point + if (nexthopIp == vrfEntry.getNextHopAddress()) { + deleteRemoteRoute(null, dpnId, vpnId, vrfTable.get().getKey(), vrfEntry); + } + } } } } @@ -614,14 +722,20 @@ public class FibManager extends AbstractDataChangeListener implements } protected String resolveAdjacency(final BigInteger localDpnId, final BigInteger remoteDpnId, - final long vpnId, final VrfEntry vrfEntry) { + final long vpnId, final VrfEntry vrfEntry, String rd) { String adjacency = null; - LOG.trace("resolveAdjacency called with localdpid{} remotedpid {}, vpnId{}, VrfEntry {}", localDpnId, remoteDpnId, vpnId, vrfEntry);; + boolean staticRoute = false; + LOG.trace("resolveAdjacency called with localdpid{} remotedpid {}, vpnId{}, VrfEntry {}", localDpnId, remoteDpnId, vpnId, vrfEntry); try { - adjacency = + Extraroute extra_route = getVpnToExtraroute(rd, vrfEntry.getDestPrefix()); + if(extra_route != null) { + staticRoute = true; + } + + adjacency = nextHopManager.getRemoteNextHopPointer(localDpnId, remoteDpnId, vpnId, - vrfEntry.getDestPrefix(), - vrfEntry.getNextHopAddress()); + (staticRoute == true) ? extra_route.getNexthopIp() + "/32" : vrfEntry.getDestPrefix(), + vrfEntry.getNextHopAddress()); } catch (NullPointerException e) { LOG.trace("", e); } @@ -631,7 +745,7 @@ public class FibManager extends AbstractDataChangeListener implements protected VpnInstanceOpDataEntry getVpnInstance(String rd) { InstanceIdentifier id = InstanceIdentifier.create(VpnInstanceOpData.class).child( VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(rd)); - Optional vpnInstanceOpData = read(LogicalDatastoreType.OPERATIONAL, id); + Optional vpnInstanceOpData = FibUtil.read(broker, LogicalDatastoreType.OPERATIONAL, id); if(vpnInstanceOpData.isPresent()) { return vpnInstanceOpData.get(); } @@ -641,7 +755,6 @@ public class FibManager extends AbstractDataChangeListener implements public void processNodeAdd(BigInteger dpnId) { LOG.debug("Received notification to install TableMiss entries for dpn {} ", dpnId); makeTableMissFlow(dpnId, NwConstants.ADD_FLOW); - makeProtocolTableFlow(dpnId, NwConstants.ADD_FLOW); makeL3IntfTblMissFlow(dpnId, NwConstants.ADD_FLOW); } @@ -710,7 +823,7 @@ public class FibManager extends AbstractDataChangeListener implements result.add(String.format(" %-7s %-20s %-20s %-7s", "RD", "Prefix", "Nexthop", "Label")); result.add("-------------------------------------------------------------------"); InstanceIdentifier id = InstanceIdentifier.create(FibEntries.class); - Optional fibEntries = read(LogicalDatastoreType.OPERATIONAL, id); + Optional fibEntries = FibUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id); if (fibEntries.isPresent()) { List vrfTables = fibEntries.get().getVrfTables(); for (VrfTables vrfTable : vrfTables) { @@ -734,7 +847,11 @@ public class FibManager extends AbstractDataChangeListener implements instructions.add(new InstructionInfo(InstructionType.clear_actions)); // Instruction to goto L3 InterfaceTable - instructions.add(new InstructionInfo(InstructionType.goto_table, new long[] { NwConstants.LPORT_DISPATCHER_TABLE })); + List actionsInfos = new ArrayList (); + actionsInfos.add(new ActionInfo(ActionType.nx_resubmit, new String[]{ + Short.toString(NwConstants.LPORT_DISPATCHER_TABLE)})); + instructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos)); + //instructions.add(new InstructionInfo(InstructionType.goto_table, new long[] { NwConstants.LPORT_DISPATCHER_TABLE })); FlowEntity flowEntityL3Intf = MDSALUtil.buildFlowEntity(dpnId, NwConstants.L3_INTERFACE_TABLE, getFlowRef(dpnId, NwConstants.L3_INTERFACE_TABLE, NwConstants.TABLE_MISS_FLOW),