use of org.opendaylight.genius.utils.batching.SubTransaction in project netvirt by opendaylight.
the class VrfEntryListener method cleanUpDpnForVpn.
public void cleanUpDpnForVpn(final BigInteger dpnId, final long vpnId, final String rd, final FutureCallback<List<Void>> callback) {
LOG.trace("cleanUpDpnForVpn: Remove dpn {} for vpn {} : cleanUpDpnForVpn", dpnId, rd);
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);
jobCoordinator.enqueueJob(FibUtil.getJobKeyForVpnIdDpnId(vpnId, dpnId), () -> {
List<ListenableFuture<Void>> futures = new ArrayList<>();
if (vrfTable.isPresent()) {
synchronized (vpnInstance.getVpnInstanceName().intern()) {
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());
}
}
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) && lri.getDpnId().equals(dpnId)) {
deleteLocalFibEntry(vpnId, rd, vrfEntry);
}
}
}
// 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;
// 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);
}
}
}));
}
if (callback != null) {
ListenableFuture<List<Void>> listenableFuture = Futures.allAsList(futures);
Futures.addCallback(listenableFuture, callback, MoreExecutors.directExecutor());
}
}
return futures;
});
}
use of org.opendaylight.genius.utils.batching.SubTransaction in project netvirt by opendaylight.
the class VrfEntryListener method createFibEntries.
private void createFibEntries(final InstanceIdentifier<VrfEntry> vrfEntryIid, final VrfEntry vrfEntry) {
final VrfTablesKey vrfTableKey = vrfEntryIid.firstKeyOf(VrfTables.class);
List<SubTransaction> txnObjects = new ArrayList<>();
final VpnInstanceOpDataEntry vpnInstance = fibUtil.getVpnInstance(vrfTableKey.getRouteDistinguisher());
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;
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() : vpnInstance.getVpnToDpnList();
LOG.info("createFibEntries: Processing creation of PNF FIB entry with rd {} prefix {}", vrfEntry.getParentVpnRd(), vrfEntry.getDestPrefix());
} else {
vpnToDpnList = vpnInstance.getVpnToDpnList();
}
final Long vpnId = vpnInstance.getVpnId();
final String rd = vrfTableKey.getRouteDistinguisher();
SubnetRoute subnetRoute = vrfEntry.getAugmentation(SubnetRoute.class);
if (subnetRoute != null) {
final long elanTag = subnetRoute.getElantag();
LOG.trace("SUBNETROUTE: createFibEntries: SubnetRoute augmented vrfentry found for rd {} prefix {}" + " with elantag {}", rd, vrfEntry.getDestPrefix(), elanTag);
if (vpnToDpnList != null) {
jobCoordinator.enqueueJob(FibUtil.getJobKeyForRdPrefix(rd, vrfEntry.getDestPrefix()), () -> {
WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
for (final VpnToDpnList curDpn : vpnToDpnList) {
if (curDpn.getDpnState() == VpnToDpnList.DpnState.Active) {
installSubnetRouteInFib(curDpn.getDpnId(), elanTag, rd, vpnId, vrfEntry, tx);
installSubnetBroadcastAddrDropRule(curDpn.getDpnId(), rd, vpnId.longValue(), vrfEntry, NwConstants.ADD_FLOW, tx);
}
}
List<ListenableFuture<Void>> futures = new ArrayList<>();
futures.add(tx.submit());
return futures;
});
}
return;
}
final List<BigInteger> localDpnIdList = createLocalFibEntry(vpnInstance.getVpnId(), rd, vrfEntry);
if (!localDpnIdList.isEmpty() && vpnToDpnList != null) {
jobCoordinator.enqueueJob(FibUtil.getJobKeyForRdPrefix(rd, vrfEntry.getDestPrefix()), () -> {
WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
synchronized (vpnInstance.getVpnInstanceName().intern()) {
for (VpnToDpnList vpnDpn : vpnToDpnList) {
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, tx, txnObjects);
} else {
createRemoteFibEntry(vpnDpn.getDpnId(), vpnInstance.getVpnId(), vrfTableKey.getRouteDistinguisher(), vrfEntry, tx);
}
} catch (NullPointerException e) {
LOG.error("Failed to get create remote fib flows for prefix {} ", vrfEntry.getDestPrefix(), e);
}
}
}
}
}
List<ListenableFuture<Void>> futures = new ArrayList<>();
futures.add(tx.submit());
return futures;
}, 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);
}
});
}
}
}
use of org.opendaylight.genius.utils.batching.SubTransaction in project netvirt by opendaylight.
the class EvpnVrfEntryHandler method createRemoteFibEntry.
private void createRemoteFibEntry(final BigInteger remoteDpnId, final long vpnId, final VrfTablesKey vrfTableKey, final VrfEntry vrfEntry, boolean isNatPrefix, WriteTransaction tx) {
String rd = vrfTableKey.getRouteDistinguisher();
List<SubTransaction> subTxns = new ArrayList<>();
LOG.debug("createremotefibentry: adding route {} for rd {} with transaction {}", vrfEntry.getDestPrefix(), rd, tx);
List<NexthopManager.AdjacencyResult> tunnelInterfaceList = resolveAdjacency(remoteDpnId, vpnId, vrfEntry, rd);
if (tunnelInterfaceList.isEmpty()) {
LOG.error("Could not get interface for route-paths: {} in vpn {}", vrfEntry.getRoutePaths(), rd);
LOG.warn("Failed to add Route: {} in vpn: {}", vrfEntry.getDestPrefix(), rd);
return;
}
for (NexthopManager.AdjacencyResult adjacencyResult : tunnelInterfaceList) {
List<ActionInfo> actionInfos = new ArrayList<>();
BigInteger tunnelId;
String prefix = adjacencyResult.getPrefix();
Prefixes prefixInfo = getFibUtil().getPrefixToInterface(vpnId, prefix);
String interfaceName = prefixInfo.getVpnInterfaceName();
if (vrfEntry.getOrigin().equals(RouteOrigin.BGP.getValue()) || isNatPrefix) {
tunnelId = BigInteger.valueOf(vrfEntry.getL3vni());
} else if (elanManager.isOpenStackVniSemanticsEnforced()) {
tunnelId = BigInteger.valueOf(getFibUtil().getVniForVxlanNetwork(prefixInfo.getSubnetId()).get());
} else {
Interface interfaceState = getFibUtil().getInterfaceStateFromOperDS(interfaceName);
tunnelId = BigInteger.valueOf(interfaceState.getIfIndex());
}
LOG.debug("adding set tunnel id action for label {}", tunnelId);
String macAddress = null;
String vpnName = getFibUtil().getVpnNameFromId(vpnId);
if (vpnName == null) {
LOG.debug("Failed to get VPN name for vpnId {}", vpnId);
return;
}
if (interfaceName != null) {
macAddress = getFibUtil().getMacAddressFromPrefix(interfaceName, vpnName, prefix);
actionInfos.add(new ActionSetFieldEthernetDestination(new MacAddress(macAddress)));
}
actionInfos.add(new ActionSetFieldTunnelId(tunnelId));
List<ActionInfo> egressActions = nexthopManager.getEgressActionsForInterface(adjacencyResult.getInterfaceName(), actionInfos.size());
if (egressActions.isEmpty()) {
LOG.error("Failed to retrieve egress action for prefix {} route-paths {} interface {}." + " Aborting remote FIB entry creation..", vrfEntry.getDestPrefix(), vrfEntry.getRoutePaths(), adjacencyResult.getInterfaceName());
return;
}
actionInfos.addAll(egressActions);
List<InstructionInfo> instructions = new ArrayList<>();
instructions.add(new InstructionApplyActions(actionInfos));
makeConnectedRoute(remoteDpnId, vpnId, vrfEntry, rd, instructions, NwConstants.ADD_FLOW, tx, subTxns);
}
LOG.debug("Successfully added FIB entry for prefix {} in rd {}", vrfEntry.getDestPrefix(), rd);
}
use of org.opendaylight.genius.utils.batching.SubTransaction in project genius by opendaylight.
the class InterfaceBatchHandler method buildSubTransactions.
private void buildSubTransactions(List<SubTransaction> transactionObjects, InstanceIdentifier identifier, Object data, short subTransactionType) {
// enable retries
SubTransaction subTransaction = new SubTransactionImpl();
subTransaction.setInstanceIdentifier(identifier);
subTransaction.setInstance(data);
subTransaction.setAction(subTransactionType);
transactionObjects.add(subTransaction);
}
use of org.opendaylight.genius.utils.batching.SubTransaction in project netvirt by opendaylight.
the class VrfEntryListener method cleanUpExternalRoutesOnDpn.
public void cleanUpExternalRoutesOnDpn(final BigInteger dpnId, final long vpnId, final String rd, final String localNextHopIp, final String remoteNextHopIp) {
LOG.trace("cleanUpExternalRoutesOnDpn : cleanup remote routes on dpn {} for vpn {}, rd {}, " + " localNexthopIp {} , remoteNexhtHopIp {}", dpnId, vpnId, rd, localNextHopIp, remoteNextHopIp);
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);
if (vrfTable.isPresent()) {
jobCoordinator.enqueueJob(FibUtil.getJobKeyForVpnIdDpnId(vpnId, dpnId), () -> {
List<ListenableFuture<Void>> futures = new ArrayList<>();
synchronized (vpnInstance.getVpnInstanceName().intern()) {
WriteTransaction writeCfgTxn = dataBroker.newWriteOnlyTransaction();
vrfTable.get().getVrfEntry().stream().filter(vrfEntry -> RouteOrigin.value(vrfEntry.getOrigin()) == RouteOrigin.BGP).forEach(bgpRouteVrfEntryHandler.getConsumerForDeletingRemoteFib(dpnId, vpnId, remoteNextHopIp, vrfTable, writeCfgTxn, txnObjects));
futures.add(writeCfgTxn.submit());
}
return futures;
});
}
}
Aggregations