*/
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;
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;
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;
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;
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;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
@Singleton
-public class VrfEntryListener extends AsyncDataTreeChangeListenerBase<VrfEntry, VrfEntryListener> {
+public class VrfEntryListener extends AbstractAsyncDataTreeChangeListener<VrfEntry> {
private static final Logger LOG = LoggerFactory.getLogger(VrfEntryListener.class);
private static final String FLOWID_PREFIX = "L3.";
private final JobCoordinator jobCoordinator;
private final IElanService elanManager;
private final FibUtil fibUtil;
- private final InterVpnLinkCache interVpnLinkCache;
private final List<AutoCloseable> closeables = new CopyOnWriteArrayList<>();
private final UpgradeState upgradeState;
private final DataTreeEventCallbackRegistrar eventCallbacks;
final RouterInterfaceVrfEntryHandler routerInterfaceVrfEntryHandler,
final JobCoordinator jobCoordinator,
final FibUtil fibUtil,
- final InterVpnLinkCache interVpnLinkCache,
final UpgradeState upgradeState,
final DataTreeEventCallbackRegistrar eventCallbacks) {
- super(VrfEntry.class, VrfEntryListener.class);
+ super(dataBroker, LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(FibEntries.class)
+ .child(VrfTables.class).child(VrfEntry.class),
+ Executors.newListeningSingleThreadExecutor("VrfEntryListener", LOG));
this.dataBroker = dataBroker;
this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
this.retryingTxRunner = new RetryingManagedNewTransactionRunner(dataBroker, MAX_RETRIES);
this.routerInterfaceVrfEntryHandler = routerInterfaceVrfEntryHandler;
this.jobCoordinator = jobCoordinator;
this.fibUtil = fibUtil;
- this.interVpnLinkCache = interVpnLinkCache;
this.upgradeState = upgradeState;
this.eventCallbacks = eventCallbacks;
}
- @Override
- @PostConstruct
public void init() {
LOG.info("{} init", getClass().getSimpleName());
- registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
}
@Override
LOG.warn("Error closing {}", c, e);
}
});
+ Executors.shutdownAndAwaitTermination(getExecutorService());
}
@Override
- protected VrfEntryListener getDataTreeChangeListener() {
- return VrfEntryListener.this;
- }
-
- @Override
- protected InstanceIdentifier<VrfEntry> getWildCardPath() {
- return InstanceIdentifier.create(FibEntries.class).child(VrfTables.class).child(VrfEntry.class);
- }
-
- @Override
- protected void add(final InstanceIdentifier<VrfEntry> identifier, final VrfEntry vrfEntry) {
+ public void add(final InstanceIdentifier<VrfEntry> 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 {}",
}
@Override
- protected void remove(InstanceIdentifier<VrfEntry> identifier, VrfEntry vrfEntry) {
+ public void remove(InstanceIdentifier<VrfEntry> 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 {}",
// "Redundant nullcheck of originalRoutePath, which is known to be non-null" - the null checking for
// originalRoutePath is a little dicey - safest to keep the checking even if not needed.
@SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE")
- protected void update(InstanceIdentifier<VrfEntry> identifier, VrfEntry original, VrfEntry update) {
+ public void update(InstanceIdentifier<VrfEntry> 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);
}
if (RouteOrigin.value(update.getOrigin()) == RouteOrigin.STATIC) {
- List<RoutePaths> originalRoutePath = original.getRoutePaths();
- List<RoutePaths> updateRoutePath = update.getRoutePaths();
+ List<RoutePaths> originalRoutePath = new ArrayList<RoutePaths>(original.nonnullRoutePaths().values());
+ List<RoutePaths> updateRoutePath = new ArrayList<RoutePaths>(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
//Update the used rds and vpntoextraroute containers only for the deleted nextHops.
List<String> nextHopsRemoved = FibHelper.getNextHopListFromRoutePaths(original);
nextHopsRemoved.removeAll(FibHelper.getNextHopListFromRoutePaths(update));
- List<ListenableFuture<Void>> futures = new ArrayList<>();
- ListenableFuture<Void> configFuture =
+ List<ListenableFuture<?>> futures = new ArrayList<>();
+ ListenableFuture<?> configFuture =
txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, configTx ->
futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, operTx ->
nextHopsRemoved.parallelStream()
}
}))));
futures.add(configFuture);
- Futures.addCallback(configFuture, new FutureCallback<Void>() {
+ Futures.addCallback(configFuture, new FutureCallback<Object>() {
@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());
Preconditions.checkNotNull(vpnInstance, "Vpn Instance not available " + vrfTableKey.getRouteDistinguisher());
Preconditions.checkNotNull(vpnInstance.getVpnId(), "Vpn Instance with rd " + vpnInstance.getVrfId()
+ " has null vpnId!");
- final Collection<VpnToDpnList> vpnToDpnList;
+ final Map<VpnToDpnListKey, VpnToDpnList> 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();
final long elanTag = subnetRoute.getElantag().toJava();
LOG.trace("SUBNETROUTE: createFibEntries: 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()) {
if (curDpn.getDpnState() == VpnToDpnList.DpnState.Active) {
installSubnetRouteInFib(curDpn.getDpnId(),
elanTag, rd, vpnId, vrfEntry, tx);
final List<Uint64> 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(),
}
})), MAX_RETRIES);
}
-
- Optional<String> 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<VrfEntry> vrfEntryId =
InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd))
.child(VrfEntry.class, new VrfEntryKey(prefix)).build();
- Optional<VrfEntry> vrfEntry = MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, vrfEntryId);
+ Optional<VrfEntry> 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());
}
void installSubnetRouteInFib(final Uint64 dpnId, final long elanTag, final String rd,
final Uint32 vpnId, final VrfEntry vrfEntry, TypedWriteTransaction<Configuration> 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;
LOG.error("Unable to get etherType for IP Prefix {}", vrfEntry.getDestPrefix());
return;
}
- FibUtil.getLabelFromRoutePaths(vrfEntry).ifPresent(label -> {
- List<String> 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<VpnInstanceOpDataEntry> 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<InstructionInfo> instructions = new ArrayList<>();
Uint64 subnetRouteMeta = Uint64.valueOf(BigInteger.valueOf(elanTag).shiftLeft(24)
.or(BigInteger.valueOf(vpnId.longValue()).shiftLeft(1)));
baseVrfEntryHandler.makeConnectedRoute(dpnId, vpnId, vrfEntry, rd, instructions,
NwConstants.ADD_FLOW, TransactionAdapter.toWriteTransaction(tx), null);
if (vrfEntry.getRoutePaths() != null) {
- for (RoutePaths routePath : vrfEntry.getRoutePaths()) {
+ for (RoutePaths routePath : vrfEntry.getRoutePaths().values()) {
if (RouteOrigin.value(vrfEntry.getOrigin()) != RouteOrigin.SELF_IMPORTED) {
List<ActionInfo> actionsInfos = new ArrayList<>();
// reinitialize instructions list for LFIB Table
.child(Table.class, new TableKey(flow.getTableId())).child(Flow.class, flowKey).build();
if (addOrRemove == NwConstants.ADD_FLOW) {
- tx.put(flowInstanceId,flow, true);
+ tx.mergeParentStructurePut(flowInstanceId,flow);
} else {
tx.delete(flowInstanceId);
}
}
- /*
- * For a given route, it installs a flow in LFIB that sets the lportTag of the other endpoint and sends to
- * LportDispatcher table (via table 80)
- */
- private void installInterVpnRouteInLFib(final InterVpnLinkDataComposite interVpnLink, final String vpnName,
- final VrfEntry vrfEntry, int etherType) {
- // INTERVPN routes are routes in a Vpn1 that have been leaked to Vpn2. In DC-GW, this Vpn2 route is pointing
- // to a list of DPNs where Vpn2's VpnLink was instantiated. In these DPNs LFIB must be programmed so that the
- // packet is commuted from Vpn2 to Vpn1.
- String interVpnLinkName = interVpnLink.getInterVpnLinkName();
- if (!interVpnLink.isActive()) {
- LOG.warn("InterVpnLink {} is NOT ACTIVE. InterVpnLink flows for prefix={} wont be installed in LFIB",
- interVpnLinkName, vrfEntry.getDestPrefix());
- return;
- }
-
- Optional<Uint32> 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<ActionInfo> actionsInfos = Collections.singletonList(new ActionPopMpls(etherType));
- List<InstructionInfo> 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<String> interVpnNextHopList = FibHelper.getNextHopListFromRoutePaths(vrfEntry);
- List<Uint64> 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<Uint32> 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<Uint64> 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<MatchInfo> 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<Instruction> 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<Uint64> createLocalFibEntry(Uint32 vpnId, String rd, VrfEntry vrfEntry, int etherType) {
List<Uint64> returnLocalDpnId = new ArrayList<>();
String localNextHopIP = vrfEntry.getDestPrefix();
return Uint64.ZERO;
}
- private boolean isVpnPresentInDpn(String rd, Uint64 dpnId) {
+ private boolean isVpnPresentInDpn(String rd, Uint64 dpnId) {
InstanceIdentifier<VpnToDpnList> id = VpnHelper.getVpnToDpnListIdentifier(rd, dpnId);
- Optional<VpnToDpnList> dpnInVpn = MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
+ Optional<VpnToDpnList> 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();
}
private LabelRouteInfo getLabelRouteInfo(LabelRouteInfoKey label) {
InstanceIdentifier<LabelRouteInfo> lriIid = InstanceIdentifier.builder(LabelRouteMap.class)
.child(LabelRouteInfo.class, label).build();
- Optional<LabelRouteInfo> opResult = MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, lriIid);
+ Optional<LabelRouteInfo> 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<Operational> tx) {
if (lri == null) {
return true;
}
-
LOG.debug("deleting LRI : for label {} vpninstancename {}", lri.getLabel(), vpnInstanceName);
InstanceIdentifier<LabelRouteInfo> lriId = InstanceIdentifier.builder(LabelRouteMap.class)
.child(LabelRouteInfo.class, new LabelRouteInfoKey(lri.getLabel())).build();
.child(Node.class, nodeDpn.key()).augmentation(FlowCapableNode.class)
.child(Table.class, new TableKey(terminatingServiceTableFlowEntity.getTableId()))
.child(Flow.class, flowKey).build();
- tx.put(flowInstanceId, flowbld.build(), CREATE_MISSING_PARENTS);
+ tx.mergeParentStructurePut(flowInstanceId, flowbld.build());
}
private void removeTunnelTableEntry(Uint64 dpId, Uint32 label, TypedWriteTransaction<Configuration> tx) {
private void createRemoteFibEntry(final Uint64 remoteDpnId, final Uint32 vpnId, String rd,
final VrfEntry vrfEntry, TypedWriteTransaction<Configuration> 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;
List<InstructionInfo> 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);
}
new CleanupVpnInterfaceWorker(prefixInfo, vpnId, rd, vrfEntry, extraRoute));
}
- private class CleanupVpnInterfaceWorker implements Callable<List<ListenableFuture<Void>>> {
+ private class CleanupVpnInterfaceWorker implements Callable<List<? extends ListenableFuture<?>>> {
Prefixes prefixInfo;
Uint32 vpnId;
String rd;
}
@Override
- public List<ListenableFuture<Void>> call() {
+ public List<? extends ListenableFuture<?>> 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 -> {
return;
}
- @NonNull List<Adjacency> adjacencies = optAdjacencies.get().nonnullAdjacency();
+ @NonNull List<Adjacency> adjacencies
+ = new ArrayList<Adjacency>(optAdjacencies.get().nonnullAdjacency().values());
if (adjacencies.size() <= 2
&& adjacencies.stream().allMatch(adjacency ->
adjacency.getAdjacencyType() == Adjacency.AdjacencyType.PrimaryAdjacency
LOG.error("VPN Instance for rd {} is not available from VPN Op Instance Datastore", rd);
return;
}
- final Collection<VpnToDpnList> vpnToDpnList;
+ final Map<VpnToDpnListKey, VpnToDpnList> 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<Uint32> optionalLabel = FibUtil.getLabelFromRoutePaths(vrfEntry);
- List<String> 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));
}
})));
}
- optionalLabel.ifPresent(label -> {
- 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<VpnInstanceOpDataEntry> 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<Uint64> localDpnIdList = deleteLocalFibEntry(vpnInstance.getVpnId(),
vrfTableKey.getRouteDistinguisher(), vrfEntry);
- if (vpnToDpnList != null) {
+ if (keyVpnToDpnListMap != null) {
List<String> usedRds = VpnExtraRouteHelper.getUsedRds(dataBroker,
vpnInstance.getVpnId(), vrfEntry.getDestPrefix());
String jobKey;
.getVpnExtraroutes(dataBroker, vpnName, usedRds.get(0), vrfEntry.getDestPrefix());
}
} else {
- extraRouteOptional = Optional.absent();
+ extraRouteOptional = Optional.empty();
}
jobCoordinator.enqueueJob(FibUtil.getJobKeyForRdPrefix(rd, vrfEntry.getDestPrefix()),
() -> 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));
}
}
}
//DS entries in VPN Op DS, VpnInstanceOpData and PrefixToInterface to complete deletion
cleanUpOpDataForFib(vpnInstance.getVpnId(), vrfTableKey.getRouteDistinguisher(), vrfEntry);
- // Remove all fib entries configured due to interVpnLink, when nexthop is the opposite endPoint
- // of the interVpnLink.
- Optional<String> optVpnUuid = fibUtil.getVpnNameFromRd(rd);
- if (optVpnUuid.isPresent()) {
- String vpnUuid = optVpnUuid.get();
- FibUtil.getFirstNextHopAddress(vrfEntry).ifPresent(routeNexthop -> {
- Optional<InterVpnLinkDataComposite> 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<InstructionInfo> instructions,
int priority, int addOrRemove, TypedWriteTransaction<Configuration> 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;
.child(Table.class, new TableKey(flow.getTableId())).child(Flow.class, flowKey).build();
if (addOrRemove == NwConstants.ADD_FLOW) {
- tx.put(flowInstanceId, flow, CREATE_MISSING_PARENTS);
+ tx.mergeParentStructurePut(flowInstanceId, flow);
} else {
tx.delete(flowInstanceId);
}
}
public void populateFibOnNewDpn(final Uint64 dpnId, final Uint32 vpnId, final String rd,
- final FutureCallback<List<Void>> callback) {
+ final FutureCallback<List<?>> callback) {
LOG.trace("New dpn {} for vpn {} : populateFibOnNewDpn", dpnId, rd);
jobCoordinator.enqueueJob(FibUtil.getJobKeyForVpnIdDpnId(vpnId, dpnId),
() -> {
final VpnInstanceOpDataEntry vpnInstance = fibUtil.getVpnInstance(rd);
final Optional<VrfTables> vrfTable = MDSALUtil.read(dataBroker,
LogicalDatastoreType.CONFIGURATION, id);
- List<ListenableFuture<Void>> futures = new ArrayList<>();
+ List<ListenableFuture<?>> futures = new ArrayList<>();
if (!vrfTable.isPresent()) {
LOG.info("populateFibOnNewDpn: dpn: {}: VRF Table not yet available for RD {}", dpnId, rd);
if (callback != null) {
- ListenableFuture<List<Void>> listenableFuture = Futures.allAsList(futures);
+ ListenableFuture<List<Object>> listenableFuture = Futures.allAsList(futures);
Futures.addCallback(listenableFuture, callback, MoreExecutors.directExecutor());
}
return futures;
lock.lock();
try {
futures.add(retryingTxRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
- 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();
}
}));
if (callback != null) {
- ListenableFuture<List<Void>> listenableFuture = Futures.allAsList(futures);
+ ListenableFuture<List<Object>> listenableFuture = Futures.allAsList(futures);
Futures.addCallback(listenableFuture, callback, MoreExecutors.directExecutor());
}
} finally {
InstanceIdentifier<VrfTables> id = buildVrfId(rd);
final VpnInstanceOpDataEntry vpnInstance = fibUtil.getVpnInstance(rd);
List<SubTransaction> txnObjects = new ArrayList<>();
- final Optional<VrfTables> vrfTable = MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
+ final Optional<VrfTables> 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));
}
LOG.trace("manageRemoteRouteOnDPN :: action {}, DpnId {}, vpnId {}, rd {}, destPfx {}",
action, localDpnId, vpnId, rd, destPrefix);
- List<RoutePaths> routePathList = vrfEntry.getRoutePaths();
+ Map<RoutePathsKey, RoutePaths> 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();
}
//Is this fib route an extra route? If yes, get the nexthop which would be
//an adjacency in the vpn
- Optional<Routes> extraRouteOptional = Optional.absent();
+ Optional<Routes> extraRouteOptional = Optional.empty();
if (RouteOrigin.value(vrfEntry.getOrigin()) == RouteOrigin.STATIC && usedRds.size() != 0) {
extraRouteOptional = VpnExtraRouteHelper.getVpnExtraroutes(dataBroker,
fibUtil.getVpnNameFromId(vpnInstance.getVpnId()),
}
public void cleanUpDpnForVpn(final Uint64 dpnId, final Uint32 vpnId, final String rd,
- final FutureCallback<List<Void>> callback) {
+ final FutureCallback<List<?>> callback) {
LOG.trace("cleanUpDpnForVpn: Remove dpn {} for vpn {} : cleanUpDpnForVpn", dpnId, rd);
jobCoordinator.enqueueJob(FibUtil.getJobKeyForVpnIdDpnId(vpnId, dpnId),
() -> {
List<SubTransaction> txnObjects = new ArrayList<>();
final Optional<VrfTables> vrfTable = MDSALUtil.read(dataBroker,
LogicalDatastoreType.CONFIGURATION, id);
- List<ListenableFuture<Void>> futures = new ArrayList<>();
+ List<ListenableFuture<?>> futures = new ArrayList<>();
if (!vrfTable.isPresent()) {
LOG.error("cleanUpDpnForVpn: VRF Table not available for RD {}", rd);
if (callback != null) {
- ListenableFuture<List<Void>> listenableFuture = Futures.allAsList(futures);
+ ListenableFuture<List<Object>> listenableFuture = Futures.allAsList(futures);
Futures.addCallback(listenableFuture, callback, MoreExecutors.directExecutor());
}
return futures;
try {
futures.add(retryingTxRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
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().
+ " for vpn {}", vrfEntry.getDestPrefix(), dpnId, rd);
baseVrfEntryHandler.makeConnectedRoute(dpnId, vpnId, vrfEntry, rd, null,
NwConstants.DEL_FLOW, TransactionAdapter.toWriteTransaction(tx), null);
- List<RoutePaths> routePaths = vrfEntry.getRoutePaths();
- if (routePaths != null) {
- for (RoutePaths routePath : routePaths) {
+ Map<RoutePathsKey, RoutePaths> keyRoutePathsMap = vrfEntry.getRoutePaths();
+ if (keyRoutePathsMap != null) {
+ for (RoutePaths routePath : keyRoutePathsMap.values()) {
makeLFibTableEntry(dpnId, routePath.getLabel(), null,
DEFAULT_FIB_FLOW_PRIORITY,
NwConstants.DEL_FLOW, tx);
}
} else {
- extraRouteOptional = Optional.absent();
+ extraRouteOptional = Optional.empty();
}
if (RouteOrigin.BGP.getValue().equals(vrfEntry.getOrigin())) {
bgpRouteVrfEntryHandler.deleteRemoteRoute(null, dpnId, vpnId,
lock.unlock();
}
if (callback != null) {
- ListenableFuture<List<Void>> listenableFuture = Futures.allAsList(futures);
+ ListenableFuture<List<Object>> listenableFuture = Futures.allAsList(futures);
Futures.addCallback(listenableFuture, callback, MoreExecutors.directExecutor());
}
return futures;
InstanceIdentifier<VrfTables> id = buildVrfId(rd);
final VpnInstanceOpDataEntry vpnInstance = fibUtil.getVpnInstance(rd);
List<SubTransaction> txnObjects = new ArrayList<>();
- final Optional<VrfTables> vrfTable = MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
+ final Optional<VrfTables> 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),
() -> {
try {
return Collections.singletonList(
txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
- tx -> 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();
}
return idBuilder.build();
}
- private String getInterVpnFibFlowRef(String interVpnLinkName, String prefix, String nextHop) {
- return FLOWID_PREFIX + interVpnLinkName + NwConstants.FLOWID_SEPARATOR + prefix + NwConstants
- .FLOWID_SEPARATOR + nextHop;
- }
-
private String getTableMissFlowRef(Uint64 dpnId, short tableId, Uint32 tableMiss) {
return FLOWID_PREFIX + dpnId + NwConstants.FLOWID_SEPARATOR + tableId + NwConstants.FLOWID_SEPARATOR
+ tableMiss + FLOWID_PREFIX;
InstanceIdentifier<VrfEntry> vrfEntryId = InstanceIdentifier.builder(FibEntries.class)
.child(VrfTables.class, new VrfTablesKey(rd))
.child(VrfEntry.class, new VrfEntryKey(ipPrefix)).build();
- Optional<VrfEntry> vrfEntry = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, vrfEntryId);
+ Optional<VrfEntry> 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<Uint64> targetDpns = interVpnLink.getEndpointDpnsByVpnName(vpnName);
-
- if (targetDpns.isEmpty()) {
- LOG.warn("Could not find DPNs for VPN {} in InterVpnLink {}", vpnName, interVpnLinkName);
- return;
- }
-
- java.util.Optional<String> optNextHop = FibUtil.getFirstNextHopAddress(vrfEntry);
- java.util.Optional<Uint32> 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<String> nextHopAddressList, LabelRouteInfo lri) {
return lri != null && Objects.equals(lri.getPrefix(), prefix)