use of org.opendaylight.mdsal.binding.util.Datastore.Configuration in project netvirt by opendaylight.
the class NeutronvpnUtils method updateVpnInstanceWithBgpVpnType.
public void updateVpnInstanceWithBgpVpnType(VpnInstance.BgpvpnType bgpvpnType, @NonNull Uuid vpnName) {
jobCoordinator.enqueueJob("VPN-" + vpnName.getValue(), () -> {
VpnInstance vpnInstance = getVpnInstance(vpnName);
if (vpnInstance == null) {
LOG.error("updateVpnInstanceWithBgpVpnType: Failed to Update VpnInstance {} with BGP-VPN type {}." + "VpnInstance is does not exist in the CONFIG. Do nothing.", vpnName.getValue(), bgpvpnType);
return Collections.emptyList();
}
if (vpnInstance.isL2vpn()) {
LOG.error("updateVpnInstanceWithBgpVpnType: Failed to Update VpnInstance {} with BGP-VPN type {}." + "VpnInstance is L2 instance. Do nothing.", vpnName.getValue(), bgpvpnType);
return Collections.emptyList();
}
VpnInstanceBuilder builder = new VpnInstanceBuilder(vpnInstance);
builder.setBgpvpnType(bgpvpnType);
InstanceIdentifier<VpnInstance> vpnIdentifier = InstanceIdentifier.builder(VpnInstances.class).child(VpnInstance.class, new VpnInstanceKey(vpnName.getValue())).build();
LOG.info("updateVpnInstanceWithBgpVpnType: Successfully updated the VpnInstance {} with BGP-VPN type {}", vpnName.getValue(), bgpvpnType);
return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> tx.merge(vpnIdentifier, builder.build())));
});
}
use of org.opendaylight.mdsal.binding.util.Datastore.Configuration in project netvirt by opendaylight.
the class NexthopManager method removeDcGwLoadBalancingGroup.
/**
* This method is invoked when the neighbor is removed from DS.
* All the LB groups which point to the given destination will be deleted.
*/
public void removeDcGwLoadBalancingGroup(Uint64 dpnId, String destinationIp) {
jobCoordinator.enqueueJob(FibHelper.getJobKeyForDcGwLoadBalancingGroup(dpnId), () -> {
List<String> availableDcGws = fibUtil.getL3VpnDcGateWays();
if (availableDcGws.contains(destinationIp)) {
availableDcGws.remove(destinationIp);
}
List<ListenableFuture<?>> futures = new ArrayList<>();
futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, operationalTx -> {
futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, configTx -> {
availableDcGws.forEach(dcGwIp -> {
List<String> dcGws = Arrays.asList(dcGwIp, destinationIp);
Collections.sort(dcGws);
String nextHopKey = FibUtil.getGreLbGroupKey(dcGws);
Optional<Nexthops> optionalNextHops = fibUtil.getNexthops(nextHopKey);
if (!optionalNextHops.isPresent()) {
return;
}
Nexthops nexthops = optionalNextHops.get();
final String groupId = nexthops.getGroupId();
final long groupIdValue = Long.parseLong(groupId);
Group group = MDSALUtil.buildGroup(groupIdValue, nextHopKey, GroupTypes.GroupSelect, MDSALUtil.buildBucketLists(Collections.emptyList()));
LOG.trace("Removed LB group {} on dpn {}", group, dpnId);
try {
mdsalApiManager.removeGroup(configTx, dpnId, group);
} catch (ExecutionException | InterruptedException e) {
LOG.error("Group removal failed for group {} with exception", groupId, e);
}
removeNextHopPointer(nextHopKey);
FibUtil.removeOrUpdateNextHopInfo(dpnId, nextHopKey, groupId, nexthops, operationalTx);
});
synchronized (getDcGateWaySyncKey(destinationIp)) {
FibUtil.removeL3vpnDcGateWay(destinationIp, operationalTx);
}
}));
}));
return futures;
}, RETRY_COUNT);
}
use of org.opendaylight.mdsal.binding.util.Datastore.Configuration in project netvirt by opendaylight.
the class NexthopManager method createDcGwLoadBalancingGroup.
public void createDcGwLoadBalancingGroup(Uint64 dpnId, String destinationIp, Class<? extends TunnelTypeBase> tunnelType) {
jobCoordinator.enqueueJob(FibHelper.getJobKeyForDcGwLoadBalancingGroup(dpnId), () -> {
List<ListenableFuture<?>> futures = new ArrayList<>();
futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, operationalTx -> {
synchronized (getDcGateWaySyncKey(destinationIp)) {
FibUtil.addL3vpnDcGateWay(destinationIp, operationalTx);
}
futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, configTx -> {
List<String> availableDcGws = getDcGwIps();
requireNonNull(availableDcGws, "There are no dc-gws present");
int noOfDcGws = availableDcGws.size();
if (noOfDcGws == 1) {
LOG.trace("There are no enough DC GateWays {} present to program LB group", availableDcGws);
return;
}
if (availableDcGws.contains(destinationIp)) {
availableDcGws.remove(destinationIp);
}
availableDcGws.forEach(dcGwIp -> {
List<String> dcGws = Arrays.asList(dcGwIp, destinationIp);
Collections.sort(dcGws);
String groupIdKey = FibUtil.getGreLbGroupKey(dcGws);
Long groupId = createNextHopPointer(groupIdKey);
List<Bucket> listBucket = new ArrayList<>();
for (int index = 0; index < dcGws.size(); index++) {
if (isTunnelUp(dcGws.get(index), dpnId, tunnelType)) {
listBucket.add(buildBucketForDcGwLbGroup(dcGws.get(index), dpnId, index, tunnelType, true));
}
}
Group group = MDSALUtil.buildGroup(groupId, groupIdKey, GroupTypes.GroupSelect, MDSALUtil.buildBucketLists(listBucket));
mdsalApiManager.addGroup(configTx, dpnId, group);
FibUtil.updateLbGroupInfo(dpnId, groupIdKey, groupId.toString(), operationalTx);
LOG.trace("LB group {} towards DC-GW installed on dpn {}. Group - {}", groupIdKey, dpnId, group);
});
}));
}));
return futures;
}, RETRY_COUNT);
}
use of org.opendaylight.mdsal.binding.util.Datastore.Configuration in project netvirt by opendaylight.
the class VrfEntryListener method populateExternalRoutesOnDpn.
public void populateExternalRoutesOnDpn(final Uint64 dpnId, final Uint32 vpnId, final String rd, final String localNextHopIp, final String remoteNextHopIp) {
LOG.trace("populateExternalRoutesOnDpn : dpn {}, vpn {}, rd {}, localNexthopIp {} , remoteNextHopIp {} ", 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;
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().values().stream().filter(vrfEntry -> RouteOrigin.BGP == RouteOrigin.value(vrfEntry.getOrigin())).forEach(bgpRouteVrfEntryHandler.getConsumerForCreatingRemoteFib(dpnId, vpnId, rd, remoteNextHopIp, vrfTable, TransactionAdapter.toWriteTransaction(tx), txnObjects));
} finally {
lock.unlock();
}
})));
}
}
use of org.opendaylight.mdsal.binding.util.Datastore.Configuration in project netvirt by opendaylight.
the class VrfEntryListener method cleanUpDpnForVpn.
public void cleanUpDpnForVpn(final Uint64 dpnId, final Uint32 vpnId, final String rd, final FutureCallback<List<?>> callback) {
LOG.trace("cleanUpDpnForVpn: Remove dpn {} for vpn {} : cleanUpDpnForVpn", dpnId, rd);
jobCoordinator.enqueueJob(FibUtil.getJobKeyForVpnIdDpnId(vpnId, dpnId), () -> {
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);
List<ListenableFuture<?>> futures = new ArrayList<>();
if (!vrfTable.isPresent()) {
LOG.error("cleanUpDpnForVpn: VRF Table not available for RD {}", rd);
if (callback != null) {
ListenableFuture<List<Object>> listenableFuture = Futures.allAsList(futures);
Futures.addCallback(listenableFuture, callback, MoreExecutors.directExecutor());
}
return futures;
}
final ReentrantLock lock = lockFor(vpnInstance);
lock.lock();
try {
futures.add(retryingTxRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
String vpnName = fibUtil.getVpnNameFromId(vpnInstance.getVpnId());
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().
* */
String parentRd = vrfEntry.getParentVpnRd() != null ? vrfEntry.getParentVpnRd() : rd;
/* Handle subnet routes here */
SubnetRoute subnetRoute = vrfEntry.augmentation(SubnetRoute.class);
if (subnetRoute != null && !fibUtil.isInterfacePresentInDpn(parentRd, dpnId)) {
LOG.trace("SUBNETROUTE: cleanUpDpnForVpn: Cleaning subnetroute {} on dpn {}" + " for vpn {}", vrfEntry.getDestPrefix(), dpnId, rd);
baseVrfEntryHandler.makeConnectedRoute(dpnId, vpnId, vrfEntry, rd, null, NwConstants.DEL_FLOW, TransactionAdapter.toWriteTransaction(tx), null);
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);
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.augmentation(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<Uint32> optionalLabel = FibUtil.getLabelFromRoutePaths(vrfEntry);
if (optionalLabel.isPresent()) {
List<String> nextHopList = FibHelper.getNextHopListFromRoutePaths(vrfEntry);
LabelRouteInfo lri = getLabelRouteInfo(optionalLabel.get());
if (isPrefixAndNextHopPresentInLri(vrfEntry.getDestPrefix(), nextHopList, lri) && Objects.equals(lri.getDpnId(), 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());
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.empty();
}
if (RouteOrigin.BGP.getValue().equals(vrfEntry.getOrigin())) {
bgpRouteVrfEntryHandler.deleteRemoteRoute(null, dpnId, vpnId, vrfTable.get().key(), vrfEntry, extraRouteOptional, TransactionAdapter.toWriteTransaction(tx), txnObjects);
} else {
if (subnetRoute == null || !fibUtil.isInterfacePresentInDpn(parentRd, dpnId)) {
baseVrfEntryHandler.deleteRemoteRoute(null, dpnId, vpnId, vrfTable.get().key(), vrfEntry, extraRouteOptional, TransactionAdapter.toWriteTransaction(tx));
}
}
}
}));
} finally {
lock.unlock();
}
if (callback != null) {
ListenableFuture<List<Object>> listenableFuture = Futures.allAsList(futures);
Futures.addCallback(listenableFuture, callback, MoreExecutors.directExecutor());
}
return futures;
});
}
Aggregations