import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.genius.infra.RetryingManagedNewTransactionRunner;
import org.opendaylight.genius.mdsalutil.ActionInfo;
import org.opendaylight.genius.mdsalutil.FlowEntity;
import org.opendaylight.genius.mdsalutil.InstructionInfo;
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.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
private static final int IPV4_ADDR_PREFIX_LENGTH = 32;
private static final int LFIB_INTERVPN_PRIORITY = 15;
public static final BigInteger COOKIE_TUNNEL = new BigInteger("9000000", 16);
- private static final int DJC_MAX_RETRIES = 3;
+ private static final int MAX_RETRIES = 3;
private static final BigInteger COOKIE_TABLE_MISS = new BigInteger("8000004", 16);
private final DataBroker dataBroker;
private final ManagedNewTransactionRunner txRunner;
+ private final RetryingManagedNewTransactionRunner retryingTxRunner;
private final IMdsalApiManager mdsalManager;
private final NexthopManager nextHopManager;
private final BgpRouteVrfEntryHandler bgpRouteVrfEntryHandler;
super(VrfEntry.class, VrfEntryListener.class);
this.dataBroker = dataBroker;
this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
+ this.retryingTxRunner = new RetryingManagedNewTransactionRunner(dataBroker, MAX_RETRIES);
this.mdsalManager = mdsalApiManager;
this.nextHopManager = nexthopManager;
this.elanManager = elanManager;
try {
operFuture.get();
} catch (InterruptedException | ExecutionException e) {
- LOG.error("Exception encountered while submitting operational future for update vrfentry {}: "
- + "{}", update, e);
+ LOG.error("Exception encountered while submitting operational future for update vrfentry {}",
+ update, e);
}
createFibEntries(identifier, update);
List<ListenableFuture<Void>> futures = new ArrayList<>();
futures.add(tx.submit());
return futures;
- }, DJC_MAX_RETRIES);
+ }, MAX_RETRIES);
}
Optional<String> optVpnUuid = fibUtil.getVpnNameFromRd(rd);
label, localNextHopInfo.getVpnInterfaceName(), lri.getDpnId());
if (vpnExtraRoutes.isEmpty()) {
BigInteger dpnId = checkCreateLocalFibEntry(localNextHopInfo, localNextHopIP,
- vpnId, rd, vrfEntry, lri.getParentVpnid(), null, vpnExtraRoutes);
+ vpnId, rd, vrfEntry, lri.getParentVpnid(), null /*vpnExtraRoute*/,
+ vpnExtraRoutes);
returnLocalDpnId.add(dpnId);
} else {
for (Routes extraRoutes : vpnExtraRoutes) {
+ " FIB processing", vrfEntry.getDestPrefix(), vpnId, rd, dpnId);
return dpnId;
}
+ if (!isVpnPresentInDpn(rd, dpnId)) {
+ LOG.error("checkCreateLocalFibEntry: The VPN with id {} rd {} is not available on dpn {}",
+ vpnId, rd, dpnId.toString());
+ return BigInteger.ZERO;
+ }
String jobKey = FibUtil.getCreateLocalNextHopJobKey(vpnId, dpnId, vrfEntry.getDestPrefix());
String interfaceName = localNextHopInfo.getVpnInterfaceName();
String prefix = vrfEntry.getDestPrefix();
String gwMacAddress = vrfEntry.getGatewayMacAddress();
//The loadbalancing group is created only if the extra route has multiple nexthops
//to avoid loadbalancing the discovered routes
- if (vpnExtraRoutes != null) {
+ if (vpnExtraRoutes != null && routes != null) {
if (isIpv4Address(routes.getNexthopIpList().get(0))) {
localNextHopIP = routes.getNexthopIpList().get(0) + NwConstants.IPV4PREFIX;
} else {
vpnExtraRoutes);
localGroupId = groupId;
} else {
- groupId = nextHopManager.getLocalNextHopGroup(parentVpnId, localNextHopIP);
+ groupId = nextHopManager.createLocalNextHop(parentVpnId, dpnId, interfaceName, localNextHopIP,
+ prefix, gwMacAddress, jobKey);
localGroupId = groupId;
}
} else {
return BigInteger.ZERO;
}
+ private boolean isVpnPresentInDpn(String rd, BigInteger dpnId) {
+ InstanceIdentifier<VpnToDpnList> id = VpnHelper.getVpnToDpnListIdentifier(rd, dpnId);
+ Optional<VpnToDpnList> dpnInVpn = MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
+ if (dpnInVpn.isPresent()) {
+ return true;
+ }
+ return false;
+ }
+
private LabelRouteInfo getLabelRouteInfo(Long label) {
InstanceIdentifier<LabelRouteInfo> lriIid = InstanceIdentifier.builder(LabelRouteMap.class)
.child(LabelRouteInfo.class, new LabelRouteInfoKey(label)).build();
List<ListenableFuture<Void>> futures = new ArrayList<>();
futures.add(tx.submit());
return futures;
- }, DJC_MAX_RETRIES);
+ }, MAX_RETRIES);
}
//The flow/group entry has been deleted from config DS; need to clean up associated operational
() -> {
List<ListenableFuture<Void>> futures = new ArrayList<>();
synchronized (vpnInstance.getVpnInstanceName().intern()) {
- WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
- for (final VrfEntry vrfEntry : vrfTable.get().getVrfEntry()) {
- SubnetRoute subnetRoute = vrfEntry.getAugmentation(SubnetRoute.class);
- if (subnetRoute != null) {
- long elanTag = subnetRoute.getElantag();
- installSubnetRouteInFib(dpnId, elanTag, rd, vpnId, vrfEntry, tx);
- installSubnetBroadcastAddrDropRule(dpnId, rd, vpnId, vrfEntry, NwConstants.ADD_FLOW, tx);
- continue;
- }
- RouterInterface routerInt = vrfEntry.getAugmentation(RouterInterface.class);
- if (routerInt != null) {
- LOG.trace("Router augmented vrfentry found rd:{}, uuid:{}, ip:{}, mac:{}",
- rd, routerInt.getUuid(), routerInt.getIpAddress(), routerInt.getMacAddress());
- routerInterfaceVrfEntryHandler.installRouterFibEntry(vrfEntry, dpnId, vpnId,
- routerInt.getIpAddress(), new MacAddress(routerInt.getMacAddress()),
- NwConstants.ADD_FLOW);
- continue;
- }
- //Handle local flow creation for imports
- if (RouteOrigin.value(vrfEntry.getOrigin()) == RouteOrigin.SELF_IMPORTED) {
- java.util.Optional<Long> optionalLabel = FibUtil.getLabelFromRoutePaths(vrfEntry);
- if (optionalLabel.isPresent()) {
- List<String> nextHopList = FibHelper.getNextHopListFromRoutePaths(vrfEntry);
- LabelRouteInfo lri = getLabelRouteInfo(optionalLabel.get());
- if (isPrefixAndNextHopPresentInLri(vrfEntry.getDestPrefix(), nextHopList, lri)) {
- if (lri.getDpnId().equals(dpnId)) {
- createLocalFibEntry(vpnId, rd, vrfEntry);
- continue;
+ futures.add(retryingTxRunner.callWithNewReadWriteTransactionAndSubmit(tx -> {
+ for (final VrfEntry vrfEntry : vrfTable.get().getVrfEntry()) {
+ SubnetRoute subnetRoute = vrfEntry.getAugmentation(SubnetRoute.class);
+ if (subnetRoute != null) {
+ long elanTag = subnetRoute.getElantag();
+ installSubnetRouteInFib(dpnId, elanTag, rd, vpnId, vrfEntry, tx);
+ installSubnetBroadcastAddrDropRule(dpnId, rd, vpnId, vrfEntry, NwConstants.ADD_FLOW,
+ tx);
+ continue;
+ }
+ RouterInterface routerInt = vrfEntry.getAugmentation(RouterInterface.class);
+ if (routerInt != null) {
+ LOG.trace("Router augmented vrfentry found rd:{}, uuid:{}, ip:{}, mac:{}",
+ rd, routerInt.getUuid(), routerInt.getIpAddress(), routerInt.getMacAddress());
+ routerInterfaceVrfEntryHandler.installRouterFibEntry(vrfEntry, dpnId, vpnId,
+ routerInt.getIpAddress(), new MacAddress(routerInt.getMacAddress()),
+ NwConstants.ADD_FLOW);
+ continue;
+ }
+ //Handle local flow creation for imports
+ if (RouteOrigin.value(vrfEntry.getOrigin()) == RouteOrigin.SELF_IMPORTED) {
+ java.util.Optional<Long> optionalLabel = FibUtil.getLabelFromRoutePaths(vrfEntry);
+ if (optionalLabel.isPresent()) {
+ List<String> nextHopList = FibHelper.getNextHopListFromRoutePaths(vrfEntry);
+ LabelRouteInfo lri = getLabelRouteInfo(optionalLabel.get());
+ if (isPrefixAndNextHopPresentInLri(vrfEntry.getDestPrefix(), nextHopList, lri)) {
+ if (lri.getDpnId().equals(dpnId)) {
+ createLocalFibEntry(vpnId, rd, vrfEntry);
+ continue;
+ }
}
}
}
- }
-
- boolean shouldCreateRemoteFibEntry = shouldCreateFibEntryForVrfAndVpnIdOnDpn(vpnId,
- vrfEntry, dpnId);
- if (shouldCreateRemoteFibEntry) {
- LOG.trace("Will create remote FIB entry for vrfEntry {} on DPN {}",
+ boolean shouldCreateRemoteFibEntry = shouldCreateFibEntryForVrfAndVpnIdOnDpn(vpnId,
vrfEntry, dpnId);
- if (RouteOrigin.BGP.getValue().equals(vrfEntry.getOrigin())) {
- bgpRouteVrfEntryHandler.createRemoteFibEntry(dpnId, vpnId,
- vrfTable.get().getRouteDistinguisher(), vrfEntry, tx, txnObjects);
- } else {
- createRemoteFibEntry(dpnId, vpnId, vrfTable.get().getRouteDistinguisher(),
- vrfEntry, tx);
+ if (shouldCreateRemoteFibEntry) {
+ LOG.trace("Will create remote FIB entry for vrfEntry {} on DPN {}", vrfEntry, dpnId);
+ if (RouteOrigin.BGP.getValue().equals(vrfEntry.getOrigin())) {
+ bgpRouteVrfEntryHandler.createRemoteFibEntry(dpnId, vpnId,
+ vrfTable.get().getRouteDistinguisher(), vrfEntry, tx, txnObjects);
+ } else {
+ createRemoteFibEntry(dpnId, vpnId, vrfTable.get().getRouteDistinguisher(),
+ vrfEntry, tx);
+ }
}
}
+ }));
+ if (callback != null) {
+ ListenableFuture<List<Void>> listenableFuture = Futures.allAsList(futures);
+ Futures.addCallback(listenableFuture, callback, MoreExecutors.directExecutor());
}
- //TODO: if we have 100K entries in FIB, can it fit in one Tranasaction (?)
- futures.add(tx.submit());
- }
- if (callback != null) {
- ListenableFuture<List<Void>> listenableFuture = Futures.allAsList(futures);
- Futures.addCallback(listenableFuture, callback, MoreExecutors.directExecutor());
}
return futures;
});
List<ListenableFuture<Void>> futures = new ArrayList<>();
if (vrfTable.isPresent()) {
synchronized (vpnInstance.getVpnInstanceName().intern()) {
- WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
- for (final VrfEntry vrfEntry : vrfTable.get().getVrfEntry()) {
+ futures.add(retryingTxRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
+ for (final VrfEntry vrfEntry : vrfTable.get().getVrfEntry()) {
/* Handle subnet routes here */
- SubnetRoute subnetRoute = vrfEntry.getAugmentation(SubnetRoute.class);
- if (subnetRoute != null) {
- LOG.trace("SUBNETROUTE: cleanUpDpnForVpn: Cleaning subnetroute {} on dpn {}"
- + " for vpn {}", vrfEntry.getDestPrefix(), dpnId, rd);
- baseVrfEntryHandler.makeConnectedRoute(dpnId, vpnId, vrfEntry, rd, null,
- NwConstants.DEL_FLOW, tx, null);
- List<RoutePaths> routePaths = vrfEntry.getRoutePaths();
- if (routePaths != null) {
- for (RoutePaths routePath : routePaths) {
- makeLFibTableEntry(dpnId, routePath.getLabel(), null,
- DEFAULT_FIB_FLOW_PRIORITY,
- NwConstants.DEL_FLOW, tx);
- LOG.trace("SUBNETROUTE: cleanUpDpnForVpn: Released subnetroute label {} for"
- + " rd {} prefix {}", routePath.getLabel(), rd,
- vrfEntry.getDestPrefix());
+ SubnetRoute subnetRoute = vrfEntry.getAugmentation(SubnetRoute.class);
+ if (subnetRoute != null) {
+ LOG.trace("SUBNETROUTE: cleanUpDpnForVpn: Cleaning subnetroute {} on dpn {}"
+ + " for vpn {}", vrfEntry.getDestPrefix(), dpnId, rd);
+ baseVrfEntryHandler.makeConnectedRoute(dpnId, vpnId, vrfEntry, rd, null,
+ NwConstants.DEL_FLOW, tx, null);
+ List<RoutePaths> routePaths = vrfEntry.getRoutePaths();
+ if (routePaths != null) {
+ for (RoutePaths routePath : routePaths) {
+ makeLFibTableEntry(dpnId, routePath.getLabel(), null,
+ DEFAULT_FIB_FLOW_PRIORITY,
+ NwConstants.DEL_FLOW, tx);
+ LOG.trace("SUBNETROUTE: cleanUpDpnForVpn: Released subnetroute label {}"
+ + " for rd {} prefix {}", routePath.getLabel(), rd,
+ vrfEntry.getDestPrefix());
+ }
}
+ installSubnetBroadcastAddrDropRule(dpnId, rd, vpnId, vrfEntry,
+ NwConstants.DEL_FLOW, tx);
+ continue;
+ }
+ // ping responder for router interfaces
+ RouterInterface routerInt = vrfEntry.getAugmentation(RouterInterface.class);
+ if (routerInt != null) {
+ LOG.trace("Router augmented vrfentry found for rd:{}, uuid:{}, ip:{}, mac:{}",
+ rd, routerInt.getUuid(), routerInt.getIpAddress(),
+ routerInt.getMacAddress());
+ routerInterfaceVrfEntryHandler.installRouterFibEntry(vrfEntry, dpnId, vpnId,
+ routerInt.getIpAddress(), new MacAddress(routerInt.getMacAddress()),
+ NwConstants.DEL_FLOW);
+ continue;
}
- installSubnetBroadcastAddrDropRule(dpnId, rd, vpnId, vrfEntry,
- NwConstants.DEL_FLOW, tx);
- continue;
- }
- // ping responder for router interfaces
- RouterInterface routerInt = vrfEntry.getAugmentation(RouterInterface.class);
- if (routerInt != null) {
- LOG.trace("Router augmented vrfentry found for rd:{}, uuid:{}, ip:{}, mac:{}",
- rd, routerInt.getUuid(), routerInt.getIpAddress(), routerInt.getMacAddress());
- routerInterfaceVrfEntryHandler.installRouterFibEntry(vrfEntry, dpnId, vpnId,
- routerInt.getIpAddress(), new MacAddress(routerInt.getMacAddress()),
- NwConstants.DEL_FLOW);
- continue;
- }
- //Handle local flow deletion for imports
- if (RouteOrigin.value(vrfEntry.getOrigin()) == RouteOrigin.SELF_IMPORTED) {
- java.util.Optional<Long> optionalLabel = FibUtil.getLabelFromRoutePaths(vrfEntry);
- if (optionalLabel.isPresent()) {
- List<String> nextHopList = FibHelper.getNextHopListFromRoutePaths(vrfEntry);
- LabelRouteInfo lri = getLabelRouteInfo(optionalLabel.get());
- if (isPrefixAndNextHopPresentInLri(vrfEntry.getDestPrefix(), nextHopList, lri)) {
- if (lri.getDpnId().equals(dpnId)) {
+ //Handle local flow deletion for imports
+ if (RouteOrigin.value(vrfEntry.getOrigin()) == RouteOrigin.SELF_IMPORTED) {
+ java.util.Optional<Long> optionalLabel = FibUtil.getLabelFromRoutePaths(vrfEntry);
+ if (optionalLabel.isPresent()) {
+ List<String> nextHopList = FibHelper.getNextHopListFromRoutePaths(vrfEntry);
+ LabelRouteInfo lri = getLabelRouteInfo(optionalLabel.get());
+ if (isPrefixAndNextHopPresentInLri(vrfEntry.getDestPrefix(), nextHopList,
+ lri) && lri.getDpnId().equals(dpnId)) {
deleteLocalFibEntry(vpnId, rd, vrfEntry);
- continue;
}
}
}
- }
- // Passing null as we don't know the dpn
- // to which prefix is attached at this point
- List<String> usedRds = VpnExtraRouteHelper.getUsedRds(dataBroker, vpnInstance.getVpnId(),
- vrfEntry.getDestPrefix());
- String vpnName = fibUtil.getVpnNameFromId(vpnInstance.getVpnId());
- Optional<Routes> extraRouteOptional;
- //Is this fib route an extra route? If yes, get the nexthop which would be
- //an adjacency in the vpn
- if (usedRds != null && !usedRds.isEmpty()) {
- if (usedRds.size() > 1) {
- LOG.error("The extra route prefix is still present in some DPNs");
- return futures;
- } else {
- extraRouteOptional = VpnExtraRouteHelper.getVpnExtraroutes(dataBroker, vpnName,
- usedRds.get(0), vrfEntry.getDestPrefix());
+ // Passing null as we don't know the dpn
+ // to which prefix is attached at this point
+ List<String> usedRds = VpnExtraRouteHelper.getUsedRds(dataBroker,
+ vpnInstance.getVpnId(), vrfEntry.getDestPrefix());
+ String vpnName = fibUtil.getVpnNameFromId(vpnInstance.getVpnId());
+ Optional<Routes> extraRouteOptional;
+ //Is this fib route an extra route? If yes, get the nexthop which would be
+ //an adjacency in the vpn
+ if (usedRds != null && !usedRds.isEmpty()) {
+ if (usedRds.size() > 1) {
+ LOG.error("The extra route prefix is still present in some DPNs");
+ return;
+ } else {
+ extraRouteOptional = VpnExtraRouteHelper.getVpnExtraroutes(dataBroker, vpnName,
+ usedRds.get(0), vrfEntry.getDestPrefix());
+ }
+ } else {
+ extraRouteOptional = Optional.absent();
+ }
+ if (RouteOrigin.BGP.getValue().equals(vrfEntry.getOrigin())) {
+ bgpRouteVrfEntryHandler.deleteRemoteRoute(null, dpnId, vpnId,
+ vrfTable.get().getKey(), vrfEntry, extraRouteOptional, tx, txnObjects);
+ } else {
+ baseVrfEntryHandler.deleteRemoteRoute(null, dpnId, vpnId, vrfTable.get().getKey(),
+ vrfEntry, extraRouteOptional, tx);
}
- } else {
- extraRouteOptional = Optional.absent();
- }
- if (RouteOrigin.BGP.getValue().equals(vrfEntry.getOrigin())) {
- bgpRouteVrfEntryHandler.deleteRemoteRoute(null, dpnId, vpnId, vrfTable.get().getKey(),
- vrfEntry, extraRouteOptional, tx, txnObjects);
- } else {
- baseVrfEntryHandler.deleteRemoteRoute(null, dpnId, vpnId, vrfTable.get().getKey(),
- vrfEntry, extraRouteOptional, tx);
}
- }
- futures.add(tx.submit());
+ }));
}
if (callback != null) {
ListenableFuture<List<Void>> listenableFuture = Futures.allAsList(futures);