X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=fibmanager%2Fimpl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fnetvirt%2Ffibmanager%2FVrfEntryListener.java;h=15c369e40b302e17cee527e10d1724ad44654166;hb=8faf4736aa6616bcd89ed2fccb84db85e1e48693;hp=013d5cbb622a3662e3bece1f84cf1339bb3d8c73;hpb=b9e1027fffd373dc86e4a9bcc52c46da3f7c4073;p=netvirt.git diff --git a/fibmanager/impl/src/main/java/org/opendaylight/netvirt/fibmanager/VrfEntryListener.java b/fibmanager/impl/src/main/java/org/opendaylight/netvirt/fibmanager/VrfEntryListener.java index 013d5cbb62..15c369e40b 100644 --- a/fibmanager/impl/src/main/java/org/opendaylight/netvirt/fibmanager/VrfEntryListener.java +++ b/fibmanager/impl/src/main/java/org/opendaylight/netvirt/fibmanager/VrfEntryListener.java @@ -7,12 +7,10 @@ */ package org.opendaylight.netvirt.fibmanager; -import static org.opendaylight.controller.md.sal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS; -import static org.opendaylight.genius.infra.Datastore.CONFIGURATION; -import static org.opendaylight.genius.infra.Datastore.OPERATIONAL; import static org.opendaylight.genius.mdsalutil.NWUtil.isIpv4Address; +import static org.opendaylight.mdsal.binding.util.Datastore.CONFIGURATION; +import static org.opendaylight.mdsal.binding.util.Datastore.OPERATIONAL; -import com.google.common.base.Optional; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import com.google.common.util.concurrent.FutureCallback; @@ -25,31 +23,21 @@ import java.net.InetAddress; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.concurrent.Callable; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.ExecutionException; import java.util.concurrent.locks.ReentrantLock; -import javax.annotation.PostConstruct; import javax.inject.Inject; import javax.inject.Singleton; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; -import org.opendaylight.controller.md.sal.binding.api.DataBroker; -import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; -import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase; +import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker; import org.opendaylight.genius.datastoreutils.listeners.DataTreeEventCallbackRegistrar; -import org.opendaylight.genius.infra.Datastore.Configuration; -import org.opendaylight.genius.infra.Datastore.Operational; -import org.opendaylight.genius.infra.ManagedNewTransactionRunner; -import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl; -import org.opendaylight.genius.infra.RetryingManagedNewTransactionRunner; -import org.opendaylight.genius.infra.TransactionAdapter; -import org.opendaylight.genius.infra.TypedReadWriteTransaction; -import org.opendaylight.genius.infra.TypedWriteTransaction; import org.opendaylight.genius.mdsalutil.ActionInfo; import org.opendaylight.genius.mdsalutil.FlowEntity; import org.opendaylight.genius.mdsalutil.InstructionInfo; @@ -71,18 +59,28 @@ import org.opendaylight.genius.mdsalutil.matches.MatchMetadata; import org.opendaylight.genius.mdsalutil.matches.MatchMplsLabel; import org.opendaylight.genius.mdsalutil.matches.MatchTunnelId; import org.opendaylight.genius.utils.JvmGlobalLocks; -import org.opendaylight.genius.utils.ServiceIndex; import org.opendaylight.genius.utils.batching.SubTransaction; import org.opendaylight.infrautils.jobcoordinator.JobCoordinator; -import org.opendaylight.infrautils.utils.concurrent.ListenableFutures; +import org.opendaylight.infrautils.utils.concurrent.Executors; +import org.opendaylight.infrautils.utils.concurrent.LoggingFutures; +import org.opendaylight.mdsal.binding.api.DataBroker; +import org.opendaylight.mdsal.binding.util.Datastore; +import org.opendaylight.mdsal.binding.util.Datastore.Configuration; +import org.opendaylight.mdsal.binding.util.Datastore.Operational; +import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunner; +import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunnerImpl; +import org.opendaylight.mdsal.binding.util.RetryingManagedNewTransactionRunner; +import org.opendaylight.mdsal.binding.util.TransactionAdapter; +import org.opendaylight.mdsal.binding.util.TypedReadWriteTransaction; +import org.opendaylight.mdsal.binding.util.TypedWriteTransaction; +import org.opendaylight.mdsal.common.api.LogicalDatastoreType; import org.opendaylight.netvirt.elanmanager.api.IElanService; import org.opendaylight.netvirt.fibmanager.NexthopManager.AdjacencyResult; import org.opendaylight.netvirt.fibmanager.api.FibHelper; import org.opendaylight.netvirt.fibmanager.api.RouteOrigin; import org.opendaylight.netvirt.vpnmanager.api.VpnExtraRouteHelper; import org.opendaylight.netvirt.vpnmanager.api.VpnHelper; -import org.opendaylight.netvirt.vpnmanager.api.intervpnlink.InterVpnLinkCache; -import org.opendaylight.netvirt.vpnmanager.api.intervpnlink.InterVpnLinkDataComposite; +import org.opendaylight.serviceutils.tools.listener.AbstractAsyncDataTreeChangeListener; import org.opendaylight.serviceutils.upgrade.UpgradeState; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; @@ -92,7 +90,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.ta import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.FibEntries; @@ -107,16 +104,17 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev15033 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntryKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentrybase.RoutePaths; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentrybase.RoutePathsKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AdjacenciesOp; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.Adjacency; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.Prefixes; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.PrefixesBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn._interface.op.data.VpnInterfaceOpDataEntry; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnListKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.to.extraroutes.vpn.extra.routes.Routes; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.link.states.InterVpnLinkState.State; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.adjacency.list.Adjacency; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.adjacency.list.AdjacencyBuilder; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder; import org.opendaylight.yangtools.yang.common.Uint32; @@ -124,9 +122,8 @@ import org.opendaylight.yangtools.yang.common.Uint64; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - @Singleton -public class VrfEntryListener extends AsyncDataTreeChangeListenerBase { +public class VrfEntryListener extends AbstractAsyncDataTreeChangeListener { private static final Logger LOG = LoggerFactory.getLogger(VrfEntryListener.class); private static final String FLOWID_PREFIX = "L3."; @@ -149,7 +146,6 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase closeables = new CopyOnWriteArrayList<>(); private final UpgradeState upgradeState; private final DataTreeEventCallbackRegistrar eventCallbacks; @@ -163,10 +159,11 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase getWildCardPath() { - return InstanceIdentifier.create(FibEntries.class).child(VrfTables.class).child(VrfEntry.class); - } - - @Override - protected void add(final InstanceIdentifier identifier, final VrfEntry vrfEntry) { + public void add(final InstanceIdentifier identifier, final VrfEntry vrfEntry) { Preconditions.checkNotNull(vrfEntry, "VrfEntry should not be null or empty."); String rd = identifier.firstKeyOf(VrfTables.class).getRouteDistinguisher(); LOG.debug("ADD: Adding Fib Entry rd {} prefix {} route-paths {}", @@ -251,7 +235,7 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase identifier, VrfEntry vrfEntry) { + public void remove(InstanceIdentifier identifier, VrfEntry vrfEntry) { Preconditions.checkNotNull(vrfEntry, "VrfEntry should not be null or empty."); String rd = identifier.firstKeyOf(VrfTables.class).getRouteDistinguisher(); LOG.debug("REMOVE: Removing Fib Entry rd {} prefix {} route-paths {}", @@ -292,11 +276,21 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase identifier, VrfEntry original, VrfEntry update) { + public void update(InstanceIdentifier identifier, VrfEntry original, VrfEntry update) { Preconditions.checkNotNull(update, "VrfEntry should not be null or empty."); final String rd = identifier.firstKeyOf(VrfTables.class).getRouteDistinguisher(); LOG.debug("UPDATE: Updating Fib Entries to rd {} prefix {} route-paths {} origin {} old-origin {}", rd, update.getDestPrefix(), update.getRoutePaths(), update.getOrigin(), original.getOrigin()); + + //Ignore any Fib Entry changes for subneroute + if (RouteOrigin.value(update.getOrigin()) == RouteOrigin.CONNECTED) { + LOG.info("UPDATE: Updated Connected Fib Entries with rd {} prefix {} old-nexthop {} " + + "new-nexthop {} origin {}", + rd, update.getDestPrefix(), original.getRoutePaths(), update.getRoutePaths(), + update.getOrigin()); + return; + } + // Handle BGP Routes first if (RouteOrigin.value(update.getOrigin()) == RouteOrigin.BGP) { bgpRouteVrfEntryHandler.updateFlows(identifier, original, update, rd); @@ -306,8 +300,8 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase originalRoutePath = original.getRoutePaths(); - List updateRoutePath = update.getRoutePaths(); + List originalRoutePath = new ArrayList(original.nonnullRoutePaths().values()); + List updateRoutePath = new ArrayList(update.nonnullRoutePaths().values()); LOG.info("UPDATE: Original route-path {} update route-path {} ", originalRoutePath, updateRoutePath); //Updates need to be handled for extraroute even if original vrf entry route path is null or @@ -340,8 +334,8 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase nextHopsRemoved = FibHelper.getNextHopListFromRoutePaths(original); nextHopsRemoved.removeAll(FibHelper.getNextHopListFromRoutePaths(update)); - List> futures = new ArrayList<>(); - ListenableFuture configFuture = + List> futures = new ArrayList<>(); + ListenableFuture configFuture = txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, configTx -> futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, operTx -> nextHopsRemoved.parallelStream() @@ -354,9 +348,9 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase() { + Futures.addCallback(configFuture, new FutureCallback() { @Override - public void onSuccess(Void result) { + public void onSuccess(Object result) { createFibEntries(identifier, update); LOG.info("UPDATE: Updated static Fib Entry with rd {} prefix {} route-paths {}", rd, update.getDestPrefix(), update.getRoutePaths()); @@ -392,17 +386,17 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase vpnToDpnList; + final Map keyVpnToDpnListMap; if (vrfEntry.getParentVpnRd() != null && FibHelper.isControllerManagedNonSelfImportedRoute(RouteOrigin.value(vrfEntry.getOrigin()))) { // This block MUST BE HIT only for PNF (Physical Network Function) FIB Entries. VpnInstanceOpDataEntry parentVpnInstance = fibUtil.getVpnInstance(vrfEntry.getParentVpnRd()); - vpnToDpnList = parentVpnInstance != null ? parentVpnInstance.getVpnToDpnList() : + keyVpnToDpnListMap = parentVpnInstance != null ? parentVpnInstance.nonnullVpnToDpnList() : vpnInstance.getVpnToDpnList(); LOG.info("createFibEntries: Processing creation of PNF FIB entry with rd {} prefix {}", vrfEntry.getParentVpnRd(), vrfEntry.getDestPrefix()); } else { - vpnToDpnList = vpnInstance.getVpnToDpnList(); + keyVpnToDpnListMap = vpnInstance.nonnullVpnToDpnList(); } final Uint32 vpnId = vpnInstance.getVpnId(); final String rd = vrfTableKey.getRouteDistinguisher(); @@ -411,11 +405,11 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase Collections.singletonList( txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> { - for (final VpnToDpnList curDpn : vpnToDpnList) { + for (final VpnToDpnList curDpn : keyVpnToDpnListMap.values()) { if (curDpn.getDpnState() == VpnToDpnList.DpnState.Active) { installSubnetRouteInFib(curDpn.getDpnId(), elanTag, rd, vpnId, vrfEntry, tx); @@ -438,21 +432,20 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase localDpnIdList = createLocalFibEntry(vpnInstance.getVpnId(), rd, vrfEntry, etherType); - if (!localDpnIdList.isEmpty() && vpnToDpnList != null) { + if (!localDpnIdList.isEmpty() && keyVpnToDpnListMap != null) { jobCoordinator.enqueueJob(FibUtil.getJobKeyForRdPrefix(rd, vrfEntry.getDestPrefix()), () -> Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> { final ReentrantLock lock = lockFor(vpnInstance); lock.lock(); try { - for (VpnToDpnList vpnDpn : vpnToDpnList) { + for (VpnToDpnList vpnDpn : keyVpnToDpnListMap.values()) { if (!localDpnIdList.contains(vpnDpn.getDpnId())) { if (vpnDpn.getDpnState() == VpnToDpnList.DpnState.Active) { try { if (RouteOrigin.BGP.getValue().equals(vrfEntry.getOrigin())) { bgpRouteVrfEntryHandler.createRemoteFibEntry(vpnDpn.getDpnId(), vpnId, vrfTableKey.getRouteDistinguisher(), vrfEntry, - TransactionAdapter.toWriteTransaction(tx), - txnObjects); + TransactionAdapter.toWriteTransaction(tx), txnObjects); } else { createRemoteFibEntry(vpnDpn.getDpnId(), vpnInstance.getVpnId(), @@ -470,30 +463,20 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase optVpnUuid = fibUtil.getVpnNameFromRd(rd); - if (optVpnUuid.isPresent()) { - String vpnUuid = optVpnUuid.get(); - InterVpnLinkDataComposite interVpnLink = interVpnLinkCache.getInterVpnLinkByVpnId(vpnUuid).orNull(); - if (interVpnLink != null) { - LOG.debug("InterVpnLink {} found in Cache linking Vpn {}", interVpnLink.getInterVpnLinkName(), vpnUuid); - FibUtil.getFirstNextHopAddress(vrfEntry).ifPresent(routeNexthop -> { - if (interVpnLink.isIpAddrTheOtherVpnEndpoint(routeNexthop, vpnUuid)) { - // This is an static route that points to the other endpoint of an InterVpnLink - // In that case, we should add another entry in FIB table pointing to LPortDispatcher table. - installIVpnLinkSwitchingFlows(interVpnLink, vpnUuid, vrfEntry, vpnId); - installInterVpnRouteInLFib(interVpnLink, vpnUuid, vrfEntry, etherType); - } - }); - } - } } void refreshFibTables(String rd, String prefix) { InstanceIdentifier vrfEntryId = InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd)) .child(VrfEntry.class, new VrfEntryKey(prefix)).build(); - Optional vrfEntry = MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, vrfEntryId); + Optional vrfEntry; + try { + vrfEntry = SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION, + vrfEntryId); + } catch (ExecutionException | InterruptedException e) { + LOG.error("refreshFibTables: Exception while reading VrfEntry Ds for the prefix {} rd {}", prefix, rd, e); + return; + } if (vrfEntry.isPresent()) { createFibEntries(vrfEntryId, vrfEntry.get()); } @@ -525,7 +508,7 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase tx) { if (tx == null) { - ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, + LoggingFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, newTx -> installSubnetRouteInFib(dpnId, elanTag, rd, vpnId, vrfEntry, newTx)), LOG, "Error installing subnet route in FIB"); return; @@ -537,32 +520,6 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase { - List nextHopAddressList = FibHelper.getNextHopListFromRoutePaths(vrfEntry); - final LabelRouteInfoKey lriKey = new LabelRouteInfoKey(label); - final ReentrantLock lock = lockFor(lriKey); - lock.lock(); - try { - LabelRouteInfo lri = getLabelRouteInfo(lriKey); - if (isPrefixAndNextHopPresentInLri(vrfEntry.getDestPrefix(), nextHopAddressList, lri)) { - - if (RouteOrigin.value(vrfEntry.getOrigin()) == RouteOrigin.SELF_IMPORTED) { - Optional vpnInstanceOpDataEntryOptional = - fibUtil.getVpnInstanceOpData(rd); - if (vpnInstanceOpDataEntryOptional.isPresent()) { - String vpnInstanceName = vpnInstanceOpDataEntryOptional.get().getVpnInstanceName(); - if (!lri.getVpnInstanceList().contains(vpnInstanceName)) { - updateVpnReferencesInLri(lri, vpnInstanceName, false); - } - } - } - LOG.debug("SUBNETROUTE: installSubnetRouteInFib: Fetched labelRouteInfo for label {} interface {}" - + " and got dpn {}", label, lri.getVpnInterfaceName(), lri.getDpnId()); - } - } finally { - lock.unlock(); - } - }); final List instructions = new ArrayList<>(); Uint64 subnetRouteMeta = Uint64.valueOf(BigInteger.valueOf(elanTag).shiftLeft(24) .or(BigInteger.valueOf(vpnId.longValue()).shiftLeft(1))); @@ -571,7 +528,7 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase actionsInfos = new ArrayList<>(); // reinitialize instructions list for LFIB Table @@ -638,136 +595,12 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase optLportTag = interVpnLink.getEndpointLportTagByVpnName(vpnName); - if (!optLportTag.isPresent()) { - LOG.warn("Could not retrieve lportTag for VPN {} endpoint in InterVpnLink {}", vpnName, interVpnLinkName); - return; - } - - Long lportTag = optLportTag.get().toJava(); - Uint32 label = FibUtil.getLabelFromRoutePaths(vrfEntry).orElse(null); - if (label == null) { - LOG.error("Could not find label in vrfEntry=[prefix={} routePaths={}]. LFIB entry for InterVpnLink skipped", - vrfEntry.getDestPrefix(), vrfEntry.getRoutePaths()); - return; - } - List actionsInfos = Collections.singletonList(new ActionPopMpls(etherType)); - List instructions = Arrays.asList( - new InstructionApplyActions(actionsInfos), - new InstructionWriteMetadata(MetaDataUtil.getMetaDataForLPortDispatcher(lportTag.intValue(), - ServiceIndex.getIndex(NwConstants.L3VPN_SERVICE_NAME, - NwConstants.L3VPN_SERVICE_INDEX)), - MetaDataUtil.getMetaDataMaskForLPortDispatcher()), - new InstructionGotoTable(NwConstants.L3_INTERFACE_TABLE)); - List interVpnNextHopList = FibHelper.getNextHopListFromRoutePaths(vrfEntry); - List targetDpns = interVpnLink.getEndpointDpnsByVpnName(vpnName); - - for (Uint64 dpId : targetDpns) { - LOG.debug("Installing flow: VrfEntry=[prefix={} label={} nexthop={}] dpn {} for InterVpnLink {} in LFIB", - vrfEntry.getDestPrefix(), label, interVpnNextHopList, dpId, interVpnLink.getInterVpnLinkName()); - - makeLFibTableEntry(dpId, label, instructions, LFIB_INTERVPN_PRIORITY, NwConstants.ADD_FLOW, - /*writeTx*/null); - } - } - - - /* - * Installs the flows in FIB table that, for a given route, do the switching from one VPN to the other. - */ - private void installIVpnLinkSwitchingFlows(final InterVpnLinkDataComposite interVpnLink, final String vpnUuid, - final VrfEntry vrfEntry, Uint32 vpnTag) { - Preconditions.checkNotNull(interVpnLink, "InterVpnLink cannot be null"); - Preconditions.checkArgument(vrfEntry.getRoutePaths() != null - && vrfEntry.getRoutePaths().size() == 1); - String destination = vrfEntry.getDestPrefix(); - String nextHop = vrfEntry.getRoutePaths().get(0).getNexthopAddress(); - String interVpnLinkName = interVpnLink.getInterVpnLinkName(); - - // After having received a static route, we should check if the vpn is part of an inter-vpn-link. - // In that case, we should populate the FIB table of the VPN pointing to LPortDisptacher table - // using as metadata the LPortTag associated to that vpn in the inter-vpn-link. - if (interVpnLink.getState().or(State.Error) != State.Active) { - LOG.warn("Route to {} with nexthop={} cannot be installed because the interVpnLink {} is not active", - destination, nextHop, interVpnLinkName); - return; - } - - Optional optOtherEndpointLportTag = interVpnLink.getOtherEndpointLportTagByVpnName(vpnUuid); - if (!optOtherEndpointLportTag.isPresent()) { - LOG.warn("Could not find suitable LportTag for the endpoint opposite to vpn {} in interVpnLink {}", - vpnUuid, interVpnLinkName); - return; - } - - List targetDpns = interVpnLink.getEndpointDpnsByVpnName(vpnUuid); - if (targetDpns.isEmpty()) { - LOG.warn("Could not find DPNs for endpoint opposite to vpn {} in interVpnLink {}", - vpnUuid, interVpnLinkName); - return; - } - - String[] values = destination.split("/"); - String destPrefixIpAddress = values[0]; - int prefixLength = values.length == 1 ? 0 : Integer.parseInt(values[1]); - - List matches = new ArrayList<>(); - matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(vpnTag.longValue()), - MetaDataUtil.METADATA_MASK_VRFID)); - matches.add(MatchEthernetType.IPV4); - - if (prefixLength != 0) { - matches.add(new MatchIpv4Destination(destPrefixIpAddress, Integer.toString(prefixLength))); - } - - List instructions = - Arrays.asList(new InstructionWriteMetadata( - MetaDataUtil.getMetaDataForLPortDispatcher(optOtherEndpointLportTag.get().intValue(), - ServiceIndex.getIndex(NwConstants.L3VPN_SERVICE_NAME, NwConstants - .L3VPN_SERVICE_INDEX)), - MetaDataUtil.getMetaDataMaskForLPortDispatcher()).buildInstruction(0), - new InstructionGotoTable(NwConstants.L3_INTERFACE_TABLE).buildInstruction(1)); - - int priority = DEFAULT_FIB_FLOW_PRIORITY + prefixLength; - String flowRef = getInterVpnFibFlowRef(interVpnLinkName, destination, nextHop); - Flow flowEntity = MDSALUtil.buildFlowNew(NwConstants.L3_FIB_TABLE, flowRef, priority, flowRef, 0, 0, - COOKIE_VM_FIB_TABLE, matches, instructions); - - LOG.trace("Installing flow in FIB table for vpn {} interVpnLink {} nextHop {} key {}", - vpnUuid, interVpnLink.getInterVpnLinkName(), nextHop, flowRef); - - for (Uint64 dpId : targetDpns) { - - LOG.debug("Installing flow: VrfEntry=[prefix={} route-paths={}] dpn {} for InterVpnLink {} in FIB", - vrfEntry.getDestPrefix(), vrfEntry.getRoutePaths(), - dpId, interVpnLink.getInterVpnLinkName()); - - mdsalManager.installFlow(dpId, flowEntity); - } - } - private List createLocalFibEntry(Uint32 vpnId, String rd, VrfEntry vrfEntry, int etherType) { List returnLocalDpnId = new ArrayList<>(); String localNextHopIP = vrfEntry.getDestPrefix(); @@ -961,9 +794,16 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase id = VpnHelper.getVpnToDpnListIdentifier(rd, dpnId); - Optional dpnInVpn = MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id); + Optional dpnInVpn; + try { + dpnInVpn = SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.OPERATIONAL, id); + } catch (ExecutionException | InterruptedException e) { + LOG.error("isVpnPresentInDpn: Exception while reading VpnToDpnList Ds for the rd {} dpnId {}", rd, + dpnId, e); + return false; + } return dpnInVpn.isPresent(); } @@ -976,19 +816,26 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase lriIid = InstanceIdentifier.builder(LabelRouteMap.class) .child(LabelRouteInfo.class, label).build(); - Optional opResult = MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, lriIid); + Optional opResult = null; + try { + opResult = SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.OPERATIONAL, + lriIid); + } catch (ExecutionException | InterruptedException e) { + LOG.error("refreshFibTables: Exception while reading LabelRouteInfo Ds for the label {}", label, e); + return null; + } if (opResult.isPresent()) { return opResult.get(); } return null; } + @SuppressFBWarnings private boolean deleteLabelRouteInfo(LabelRouteInfo lri, String vpnInstanceName, @Nullable TypedWriteTransaction tx) { if (lri == null) { return true; } - LOG.debug("deleting LRI : for label {} vpninstancename {}", lri.getLabel(), vpnInstanceName); InstanceIdentifier lriId = InstanceIdentifier.builder(LabelRouteMap.class) .child(LabelRouteInfo.class, new LabelRouteInfoKey(lri.getLabel())).build(); @@ -1056,7 +903,7 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase tx) { @@ -1200,7 +1047,7 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase tx) { if (tx == null) { - ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, + LoggingFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, newTx -> createRemoteFibEntry(remoteDpnId, vpnId, rd, vrfEntry, newTx)), LOG, "Error creating remote FIB entry"); return; @@ -1252,10 +1099,11 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase instructions = Lists.newArrayList(new InstructionApplyActions(actionInfos)); String jobKey = FibUtil.getCreateRemoteNextHopJobKey(vpnId, remoteDpnId, vrfEntry.getDestPrefix()); jobCoordinator.enqueueJob(jobKey, - () -> Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(txn -> { - baseVrfEntryHandler.makeConnectedRoute(remoteDpnId, vpnId, vrfEntry, rd, instructions, - NwConstants.ADD_FLOW, txn, null); - }))); + () -> Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(Datastore.CONFIGURATION, + txn -> { + baseVrfEntryHandler.makeConnectedRoute(remoteDpnId, vpnId, vrfEntry, rd, instructions, + NwConstants.ADD_FLOW, TransactionAdapter.toWriteTransaction(txn), null); + }))); LOG.debug("Successfully added FIB entry for prefix {} in vpnId {}", vrfEntry.getDestPrefix(), vpnId); } @@ -1347,7 +1195,7 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase>> { + private class CleanupVpnInterfaceWorker implements Callable>> { Prefixes prefixInfo; Uint32 vpnId; String rd; @@ -1364,7 +1212,7 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase> call() { + public List> call() { // If another renderer(for eg : CSS) needs to be supported, check can be performed here // to call the respective helpers. return Collections.singletonList(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, tx -> { @@ -1481,7 +1329,8 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase adjacencies = optAdjacencies.get().nonnullAdjacency(); + @NonNull List adjacencies + = new ArrayList(optAdjacencies.get().nonnullAdjacency().values()); if (adjacencies.size() <= 2 && adjacencies.stream().allMatch(adjacency -> adjacency.getAdjacencyType() == Adjacency.AdjacencyType.PrimaryAdjacency @@ -1501,37 +1350,36 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase vpnToDpnList; + final Map keyVpnToDpnListMap; if (vrfEntry.getParentVpnRd() != null && FibHelper.isControllerManagedNonSelfImportedRoute(RouteOrigin.value(vrfEntry.getOrigin()))) { // This block MUST BE HIT only for PNF (Physical Network Function) FIB Entries. VpnInstanceOpDataEntry parentVpnInstance = fibUtil.getVpnInstance(vrfEntry.getParentVpnRd()); - vpnToDpnList = parentVpnInstance != null ? parentVpnInstance.getVpnToDpnList() : + keyVpnToDpnListMap = parentVpnInstance != null ? parentVpnInstance.getVpnToDpnList() : vpnInstance.getVpnToDpnList(); LOG.info("deleteFibEntries: Processing deletion of PNF FIB entry with rd {} prefix {}", vrfEntry.getParentVpnRd(), vrfEntry.getDestPrefix()); } else { - vpnToDpnList = vpnInstance.getVpnToDpnList(); + keyVpnToDpnListMap = vpnInstance.getVpnToDpnList(); } SubnetRoute subnetRoute = vrfEntry.augmentation(SubnetRoute.class); final java.util.Optional optionalLabel = FibUtil.getLabelFromRoutePaths(vrfEntry); - List nextHopAddressList = FibHelper.getNextHopListFromRoutePaths(vrfEntry); String vpnName = fibUtil.getVpnNameFromId(vpnInstance.getVpnId()); if (subnetRoute != null) { long elanTag = subnetRoute.getElantag().toJava(); LOG.trace("SUBNETROUTE: deleteFibEntries: SubnetRoute augmented vrfentry found for rd {} prefix {}" + " with elantag {}", rd, vrfEntry.getDestPrefix(), elanTag); - if (vpnToDpnList != null) { + if (keyVpnToDpnListMap != null) { jobCoordinator.enqueueJob(FibUtil.getJobKeyForRdPrefix(rd, vrfEntry.getDestPrefix()), () -> Collections.singletonList( txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> { - for (final VpnToDpnList curDpn : vpnToDpnList) { + for (final VpnToDpnList curDpn : keyVpnToDpnListMap.values()) { baseVrfEntryHandler.makeConnectedRoute(curDpn.getDpnId(), vpnInstance.getVpnId(), - vrfEntry, vrfTableKey.getRouteDistinguisher(), null, NwConstants.DEL_FLOW, - TransactionAdapter.toWriteTransaction(tx), null); + vrfEntry, vrfTableKey.getRouteDistinguisher(), null, + NwConstants.DEL_FLOW, TransactionAdapter.toWriteTransaction(tx), null); if (RouteOrigin.value(vrfEntry.getOrigin()) != RouteOrigin.SELF_IMPORTED) { optionalLabel.ifPresent(label -> makeLFibTableEntry(curDpn.getDpnId(), label, null, DEFAULT_FIB_FLOW_PRIORITY, NwConstants.DEL_FLOW, tx)); @@ -1543,43 +1391,12 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase { - final LabelRouteInfoKey lriKey = new LabelRouteInfoKey(label); - final ReentrantLock lock = lockFor(lriKey); - lock.lock(); - try { - LabelRouteInfo lri = getLabelRouteInfo(lriKey); - if (isPrefixAndNextHopPresentInLri(vrfEntry.getDestPrefix(), nextHopAddressList, lri)) { - Optional vpnInstanceOpDataEntryOptional = - fibUtil.getVpnInstanceOpData(rd); - String vpnInstanceName = ""; - if (vpnInstanceOpDataEntryOptional.isPresent()) { - vpnInstanceName = vpnInstanceOpDataEntryOptional.get().getVpnInstanceName(); - } - boolean lriRemoved = this.deleteLabelRouteInfo(lri, vpnInstanceName, null); - if (lriRemoved) { - String parentRd = lri.getParentVpnRd(); - fibUtil.releaseId(FibConstants.VPN_IDPOOL_NAME, FibUtil.getNextHopLabelKey( - parentRd, vrfEntry.getDestPrefix())); - LOG.trace("SUBNETROUTE: deleteFibEntries: Released subnetroute label {} for rd {} prefix {}" - + " as labelRouteInfo cleared", label, rd, vrfEntry.getDestPrefix()); - } - } else { - fibUtil.releaseId(FibConstants.VPN_IDPOOL_NAME, FibUtil.getNextHopLabelKey( - rd, vrfEntry.getDestPrefix())); - LOG.trace("SUBNETROUTE: deleteFibEntries: Released subnetroute label {} for rd {} prefix {}", - label, rd, vrfEntry.getDestPrefix()); - } - } finally { - lock.unlock(); - } - }); return; } final List localDpnIdList = deleteLocalFibEntry(vpnInstance.getVpnId(), vrfTableKey.getRouteDistinguisher(), vrfEntry); - if (vpnToDpnList != null) { + if (keyVpnToDpnListMap != null) { List usedRds = VpnExtraRouteHelper.getUsedRds(dataBroker, vpnInstance.getVpnId(), vrfEntry.getDestPrefix()); String jobKey; @@ -1596,24 +1413,24 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> { if (localDpnIdList.size() <= 0) { - for (VpnToDpnList curDpn : vpnToDpnList) { + for (VpnToDpnList curDpn : keyVpnToDpnListMap.values()) { baseVrfEntryHandler.deleteRemoteRoute(Uint64.ZERO, curDpn.getDpnId(), vpnInstance.getVpnId(), vrfTableKey, vrfEntry, extraRouteOptional, - TransactionAdapter.toWriteTransaction(tx)); + TransactionAdapter.toWriteTransaction(tx)); } } else { for (Uint64 localDpnId : localDpnIdList) { - for (VpnToDpnList curDpn : vpnToDpnList) { + for (VpnToDpnList curDpn : keyVpnToDpnListMap.values()) { if (!Objects.equals(curDpn.getDpnId(), localDpnId)) { baseVrfEntryHandler.deleteRemoteRoute(localDpnId, curDpn.getDpnId(), vpnInstance.getVpnId(), vrfTableKey, vrfEntry, extraRouteOptional, - TransactionAdapter.toWriteTransaction(tx)); + TransactionAdapter.toWriteTransaction(tx)); } } } @@ -1632,31 +1449,12 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase optVpnUuid = fibUtil.getVpnNameFromRd(rd); - if (optVpnUuid.isPresent()) { - String vpnUuid = optVpnUuid.get(); - FibUtil.getFirstNextHopAddress(vrfEntry).ifPresent(routeNexthop -> { - Optional optInterVpnLink = interVpnLinkCache.getInterVpnLinkByVpnId(vpnUuid); - if (optInterVpnLink.isPresent()) { - InterVpnLinkDataComposite interVpnLink = optInterVpnLink.get(); - if (interVpnLink.isIpAddrTheOtherVpnEndpoint(routeNexthop, vpnUuid)) { - // This is route that points to the other endpoint of an InterVpnLink - // In that case, we should look for the FIB table pointing to - // LPortDispatcher table and remove it. - removeInterVPNLinkRouteFlows(interVpnLink, vpnUuid, vrfEntry); - } - } - }); - } - } private void makeLFibTableEntry(Uint64 dpId, Uint32 label, @Nullable List instructions, int priority, int addOrRemove, TypedWriteTransaction tx) { if (tx == null) { - ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, + LoggingFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, newTx -> makeLFibTableEntry(dpId, label, instructions, priority, addOrRemove, newTx)), LOG, "Error making LFIB table entry"); return; @@ -1681,7 +1479,7 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase> callback) { + final FutureCallback> callback) { LOG.trace("New dpn {} for vpn {} : populateFibOnNewDpn", dpnId, rd); jobCoordinator.enqueueJob(FibUtil.getJobKeyForVpnIdDpnId(vpnId, dpnId), () -> { @@ -1699,11 +1497,11 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase vrfTable = MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id); - List> futures = new ArrayList<>(); + List> futures = new ArrayList<>(); if (!vrfTable.isPresent()) { LOG.info("populateFibOnNewDpn: dpn: {}: VRF Table not yet available for RD {}", dpnId, rd); if (callback != null) { - ListenableFuture> listenableFuture = Futures.allAsList(futures); + ListenableFuture> listenableFuture = Futures.allAsList(futures); Futures.addCallback(listenableFuture, callback, MoreExecutors.directExecutor()); } return futures; @@ -1713,7 +1511,7 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase { - for (final VrfEntry vrfEntry : vrfTable.get().nonnullVrfEntry()) { + for (final VrfEntry vrfEntry : vrfTable.get().nonnullVrfEntry().values()) { SubnetRoute subnetRoute = vrfEntry.augmentation(SubnetRoute.class); if (subnetRoute != null) { long elanTag = subnetRoute.getElantag().toJava(); @@ -1769,7 +1567,7 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase> listenableFuture = Futures.allAsList(futures); + ListenableFuture> listenableFuture = Futures.allAsList(futures); Futures.addCallback(listenableFuture, callback, MoreExecutors.directExecutor()); } } finally { @@ -1786,14 +1584,20 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase id = buildVrfId(rd); final VpnInstanceOpDataEntry vpnInstance = fibUtil.getVpnInstance(rd); List txnObjects = new ArrayList<>(); - final Optional vrfTable = MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id); + final Optional vrfTable; + try { + vrfTable = SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION, id); + } catch (ExecutionException | InterruptedException e) { + LOG.error("populateExternalRoutesOnDpn: Exception while reading the VrfTable for the rd {}", rd, e); + return; + } if (vrfTable.isPresent()) { jobCoordinator.enqueueJob(FibUtil.getJobKeyForVpnIdDpnId(vpnId, dpnId), () -> Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> { final ReentrantLock lock = lockFor(vpnInstance); lock.lock(); try { - vrfTable.get().nonnullVrfEntry().stream() + vrfTable.get().nonnullVrfEntry().values().stream() .filter(vrfEntry -> RouteOrigin.BGP == RouteOrigin.value(vrfEntry.getOrigin())) .forEach(bgpRouteVrfEntryHandler.getConsumerForCreatingRemoteFib(dpnId, vpnId, rd, remoteNextHopIp, vrfTable, TransactionAdapter.toWriteTransaction(tx), txnObjects)); @@ -1830,9 +1634,9 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase routePathList = vrfEntry.getRoutePaths(); + Map keyRoutePathsMap = vrfEntry.getRoutePaths(); VrfEntry modVrfEntry; - if (routePathList == null || routePathList.isEmpty()) { + if (keyRoutePathsMap == null || keyRoutePathsMap.isEmpty()) { modVrfEntry = FibHelper.getVrfEntryBuilder(vrfEntry, label, Collections.singletonList(destTepIp), RouteOrigin.value(vrfEntry.getOrigin()), null /* parentVpnRd */).build(); @@ -1854,7 +1658,7 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase extraRouteOptional = Optional.absent(); + Optional extraRouteOptional = Optional.empty(); if (RouteOrigin.value(vrfEntry.getOrigin()) == RouteOrigin.STATIC && usedRds.size() != 0) { extraRouteOptional = VpnExtraRouteHelper.getVpnExtraroutes(dataBroker, fibUtil.getVpnNameFromId(vpnInstance.getVpnId()), @@ -1870,7 +1674,7 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase> callback) { + final FutureCallback> callback) { LOG.trace("cleanUpDpnForVpn: Remove dpn {} for vpn {} : cleanUpDpnForVpn", dpnId, rd); jobCoordinator.enqueueJob(FibUtil.getJobKeyForVpnIdDpnId(vpnId, dpnId), () -> { @@ -1879,11 +1683,11 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase txnObjects = new ArrayList<>(); final Optional vrfTable = MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id); - List> futures = new ArrayList<>(); + List> futures = new ArrayList<>(); if (!vrfTable.isPresent()) { LOG.error("cleanUpDpnForVpn: VRF Table not available for RD {}", rd); if (callback != null) { - ListenableFuture> listenableFuture = Futures.allAsList(futures); + ListenableFuture> listenableFuture = Futures.allAsList(futures); Futures.addCallback(listenableFuture, callback, MoreExecutors.directExecutor()); } return futures; @@ -1893,7 +1697,7 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase { String vpnName = fibUtil.getVpnNameFromId(vpnInstance.getVpnId()); - for (final VrfEntry vrfEntry : vrfTable.get().nonnullVrfEntry()) { + for (final VrfEntry vrfEntry : vrfTable.get().nonnullVrfEntry().values()) { /* parentRd is only filled for external PNF cases where the interface on the external * network VPN are used to cleanup the flows. For all other cases, use "rd" for * #fibUtil.isInterfacePresentInDpn(). @@ -1908,9 +1712,9 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase routePaths = vrfEntry.getRoutePaths(); - if (routePaths != null) { - for (RoutePaths routePath : routePaths) { + Map keyRoutePathsMap = vrfEntry.getRoutePaths(); + if (keyRoutePathsMap != null) { + for (RoutePaths routePath : keyRoutePathsMap.values()) { makeLFibTableEntry(dpnId, routePath.getLabel(), null, DEFAULT_FIB_FLOW_PRIORITY, NwConstants.DEL_FLOW, tx); @@ -1963,7 +1767,7 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase> listenableFuture = Futures.allAsList(futures); + ListenableFuture> listenableFuture = Futures.allAsList(futures); Futures.addCallback(listenableFuture, callback, MoreExecutors.directExecutor()); } return futures; @@ -1998,7 +1802,13 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase id = buildVrfId(rd); final VpnInstanceOpDataEntry vpnInstance = fibUtil.getVpnInstance(rd); List txnObjects = new ArrayList<>(); - final Optional vrfTable = MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id); + final Optional vrfTable; + try { + vrfTable = SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION, id); + } catch (ExecutionException | InterruptedException e) { + LOG.error("getVrfEntry: Exception while reading VrfTable for the rd {} vpnId {}", rd, vpnId, e); + return; + } if (vrfTable.isPresent()) { jobCoordinator.enqueueJob(FibUtil.getJobKeyForVpnIdDpnId(vpnId, dpnId), () -> { @@ -2007,11 +1817,11 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase vrfTable.get().nonnullVrfEntry().stream() + tx -> vrfTable.get().nonnullVrfEntry().values().stream() .filter(vrfEntry -> RouteOrigin.value(vrfEntry.getOrigin()) == RouteOrigin.BGP) .forEach(bgpRouteVrfEntryHandler.getConsumerForDeletingRemoteFib(dpnId, vpnId, remoteNextHopIp, vrfTable, TransactionAdapter.toWriteTransaction(tx), - txnObjects)))); + txnObjects)))); } finally { lock.unlock(); } @@ -2025,11 +1835,6 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase vrfEntryId = InstanceIdentifier.builder(FibEntries.class) .child(VrfTables.class, new VrfTablesKey(rd)) .child(VrfEntry.class, new VrfEntryKey(ipPrefix)).build(); - Optional vrfEntry = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, vrfEntryId); + Optional vrfEntry; + try { + vrfEntry = SingleTransactionDataBroker.syncReadOptional(broker, LogicalDatastoreType.CONFIGURATION, + vrfEntryId); + } catch (ExecutionException | InterruptedException e) { + LOG.error("getVrfEntry: Exception while reading VrfEntry for the prefix {} rd {}", ipPrefix, rd, e); + return null; + } if (vrfEntry.isPresent()) { return vrfEntry.get(); } return null; } - public void removeInterVPNLinkRouteFlows(final InterVpnLinkDataComposite interVpnLink, - final String vpnName, - final VrfEntry vrfEntry) { - Preconditions.checkArgument(vrfEntry.getRoutePaths() != null && vrfEntry.getRoutePaths().size() == 1); - - String interVpnLinkName = interVpnLink.getInterVpnLinkName(); - List targetDpns = interVpnLink.getEndpointDpnsByVpnName(vpnName); - - if (targetDpns.isEmpty()) { - LOG.warn("Could not find DPNs for VPN {} in InterVpnLink {}", vpnName, interVpnLinkName); - return; - } - - java.util.Optional optNextHop = FibUtil.getFirstNextHopAddress(vrfEntry); - java.util.Optional optLabel = FibUtil.getLabelFromRoutePaths(vrfEntry); - - // delete from FIB - // - optNextHop.ifPresent(nextHop -> { - String flowRef = getInterVpnFibFlowRef(interVpnLinkName, vrfEntry.getDestPrefix(), nextHop); - FlowKey flowKey = new FlowKey(new FlowId(flowRef)); - Flow flow = new FlowBuilder().withKey(flowKey).setId(new FlowId(flowRef)) - .setTableId(NwConstants.L3_FIB_TABLE).setFlowName(flowRef).build(); - - LOG.trace("Removing flow in FIB table for interVpnLink {} key {}", interVpnLinkName, flowRef); - for (Uint64 dpId : targetDpns) { - LOG.debug("Removing flow: VrfEntry=[prefix={} nexthop={}] dpn {} for InterVpnLink {} in FIB", - vrfEntry.getDestPrefix(), nextHop, dpId, interVpnLinkName); - - mdsalManager.removeFlow(dpId, flow); - } - }); - - // delete from LFIB - // - optLabel.ifPresent(label -> { - LOG.trace("Removing flow in FIB table for interVpnLink {}", interVpnLinkName); - - ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> { - for (Uint64 dpId : targetDpns) { - LOG.debug("Removing flow: VrfEntry=[prefix={} label={}] dpn {} for InterVpnLink {} in LFIB", - vrfEntry.getDestPrefix(), label, dpId, interVpnLinkName); - makeLFibTableEntry(dpId, label, /*instructions*/null, LFIB_INTERVPN_PRIORITY, - NwConstants.DEL_FLOW, tx); - } - }), LOG, "Error removing flows"); - }); - } - private static boolean isPrefixAndNextHopPresentInLri(String prefix, List nextHopAddressList, LabelRouteInfo lri) { return lri != null && Objects.equals(lri.getPrefix(), prefix)