use of org.opendaylight.mdsal.binding.util.Datastore.CONFIGURATION in project netvirt by opendaylight.
the class NodeConnectedHandlerTest method testD1Connect.
@Test
// need to fix this Test. Actual functionality is fine
@Ignore
public void testD1Connect() throws Exception {
ManagedNewTransactionRunner txRunner = new ManagedNewTransactionRunnerImpl(getDataBroker());
txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL, tx -> handlerUtils.addPsNode(d1PsNodePath, d1NodePath, DataProvider.getPortNameListD1(), tx)).get();
txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL, tx -> handlerUtils.addNode(d1NodePath, d1PsNodePath, DataProvider.getLogicalSwitchDataD1(), DataProvider.getLocalUcasMacDataD1(), DataProvider.getLocalMcastDataD1(), DataProvider.getRemoteMcastDataD1(), DataProvider.getRemoteUcasteMacDataD1(), DataProvider.getGlobalTerminationPointIpD1(), tx)).get();
readNodes();
txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, confTx -> txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, operTx -> nodeConnectedHandler.handleNodeConnected(d1GlobalOpNode.get(), d1NodePath, haNodePath, haGlobalConfigNode, haPsConfigNode, confTx, operTx)).get()).get();
readNodes();
// verify global ha manager config should have ha_children
Assert.assertTrue(haGlobalConfigNode.isPresent());
Assert.assertTrue(d1GlobalOpNode.isPresent());
TestUtil.verifyHAconfigNode(haGlobalConfigNode.get(), d1GlobalOpNode.get());
Assert.assertTrue(d1GlobalOpNode.isPresent());
Assert.assertTrue(haGlobalOpNode.isPresent());
Assert.assertTrue(d1PsOpNode.isPresent());
Assert.assertTrue(haPsOpNode.isPresent());
TestUtil.verifyHAOpNode(d1GlobalOpNode.get(), haGlobalOpNode.get(), d1PsOpNode.get(), haPsOpNode.get(), haNodePath, d1PsNodePath, haPsNodePath, getDataBroker());
}
use of org.opendaylight.mdsal.binding.util.Datastore.CONFIGURATION in project netvirt by opendaylight.
the class VpnInterfaceManager method addVpnInterfaceToVpn.
private void addVpnInterfaceToVpn(final InstanceIdentifier<VpnInterfaceOpDataEntry> vpnInterfaceOpIdentifier, final VpnInterface vpnInterface, @Nullable final List<Adjacency> oldAdjs, @Nullable final List<Adjacency> newAdjs, final InstanceIdentifier<VpnInterface> identifier, String vpnName) {
final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class);
final String interfaceName = key.getName();
String primaryRd = vpnUtil.getPrimaryRd(vpnName);
if (!vpnUtil.isVpnPendingDelete(primaryRd)) {
Interface interfaceState = InterfaceUtils.getInterfaceStateFromOperDS(dataBroker, interfaceName);
boolean isBgpVpnInternetVpn = vpnUtil.isBgpVpnInternet(vpnName);
if (interfaceState != null) {
try {
final Uint64 dpnId = InterfaceUtils.getDpIdFromInterface(interfaceState);
final int ifIndex = interfaceState.getIfIndex();
jobCoordinator.enqueueJob("VPNINTERFACE-" + interfaceName, () -> {
// TODO Deal with sequencing — the config tx must only submitted if the oper tx goes in
// (the inventory tx goes in last)
List<ListenableFuture<?>> futures = new ArrayList<>();
// set of prefix used, as entry in prefix-to-interface datastore
// is prerequisite for refresh Fib to avoid race condition leading to
// missing remote next hop in bucket actions on bgp-vpn delete
Set<String> prefixListForRefreshFib = new HashSet<>();
ListenableFuture<?> confFuture = txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, confTx -> futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL, operTx -> futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, invTx -> {
LOG.info("addVpnInterface: VPN Interface add event - intfName {} vpnName {}" + " on dpn {}", vpnInterface.getName(), vpnName, vpnInterface.getDpnId());
processVpnInterfaceUp(dpnId, vpnInterface, primaryRd, ifIndex, false, confTx, operTx, invTx, interfaceState, vpnName, prefixListForRefreshFib);
if (oldAdjs != null && !oldAdjs.equals(newAdjs)) {
LOG.info("addVpnInterface: Adjacency changed upon VPNInterface {}" + " Update for swapping VPN {} case.", interfaceName, vpnName);
if (newAdjs != null) {
for (Adjacency adj : newAdjs) {
if (oldAdjs.contains(adj)) {
oldAdjs.remove(adj);
} else {
if (!isBgpVpnInternetVpn || vpnUtil.isAdjacencyEligibleToVpnInternet(adj)) {
addNewAdjToVpnInterface(vpnInterfaceOpIdentifier, primaryRd, adj, dpnId, operTx, confTx, invTx, prefixListForRefreshFib);
}
}
}
}
for (Adjacency adj : oldAdjs) {
if (!isBgpVpnInternetVpn || vpnUtil.isAdjacencyEligibleToVpnInternet(adj)) {
delAdjFromVpnInterface(vpnInterfaceOpIdentifier, adj, dpnId, operTx, confTx);
}
}
}
})))));
Futures.addCallback(confFuture, new VpnInterfaceCallBackHandler(primaryRd, prefixListForRefreshFib), MoreExecutors.directExecutor());
futures.add(confFuture);
Futures.addCallback(confFuture, new PostVpnInterfaceWorker(interfaceName, true, "Config"), MoreExecutors.directExecutor());
LOG.info("addVpnInterface: Addition of interface {} in VPN {} on dpn {}" + " processed successfully", interfaceName, vpnName, dpnId);
return futures;
});
} catch (NumberFormatException | IllegalStateException e) {
LOG.error("addVpnInterface: Unable to retrieve dpnId from interface operational data store for " + "interface {}. Interface addition on vpn {} failed", interfaceName, vpnName, e);
return;
}
} else if (Boolean.TRUE.equals(vpnInterface.isRouterInterface())) {
jobCoordinator.enqueueJob("VPNINTERFACE-" + vpnInterface.getName(), () -> {
ListenableFuture<?> future = txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, confTx -> {
createFibEntryForRouterInterface(primaryRd, vpnInterface, interfaceName, confTx, vpnName);
LOG.info("addVpnInterface: Router interface {} for vpn {} on dpn {}", interfaceName, vpnName, vpnInterface.getDpnId());
});
LoggingFutures.addErrorLogging(future, LOG, "Error creating FIB entry for interface {} on VPN {}", vpnInterface.getName(), vpnName);
return Collections.singletonList(future);
});
} else {
LOG.info("addVpnInterface: Handling addition of VPN interface {} on vpn {} skipped as interfaceState" + " is not available", interfaceName, vpnName);
}
} else {
LOG.error("addVpnInterface: Handling addition of VPN interface {} on vpn {} dpn {} skipped" + " as vpn is pending delete", interfaceName, vpnName, vpnInterface.getDpnId());
}
}
use of org.opendaylight.mdsal.binding.util.Datastore.CONFIGURATION in project netvirt by opendaylight.
the class VpnInterfaceOpListener method postProcessVpnInterfaceRemoval.
private void postProcessVpnInterfaceRemoval(InstanceIdentifier<VpnInterfaceOpDataEntry> identifier, VpnInterfaceOpDataEntry del, @Nullable TypedReadWriteTransaction<Operational> operTx, @Nullable TypedReadTransaction<Configuration> confTx) throws InterruptedException {
if (confTx == null) {
txRunner.callWithNewReadOnlyTransactionAndClose(CONFIGURATION, tx -> postProcessVpnInterfaceRemoval(identifier, del, operTx, tx));
return;
}
if (operTx == null) {
LoggingFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, tx -> postProcessVpnInterfaceRemoval(identifier, del, tx, confTx)), LOG, "Error post-processing VPN interface removal");
return;
}
final VpnInterfaceOpDataEntryKey key = identifier.firstKeyOf(VpnInterfaceOpDataEntry.class);
String interfaceName = key.getName();
String vpnName = del.getVpnInstanceName();
try {
LOG.info("postProcessVpnInterfaceRemoval: interface name {} vpnName {} dpn {}", interfaceName, vpnName, del.getDpnId());
// decrement the vpn interface count in Vpn Instance Op Data
Optional<VpnInstance> vpnInstance = confTx.read(VpnOperDsUtils.getVpnInstanceToVpnIdIdentifier(vpnName)).get();
if (vpnInstance.isPresent()) {
String rd = vpnInstance.get().getVrfId();
VpnInstanceOpDataEntry vpnInstOp = vpnUtil.getVpnInstanceOpData(rd);
AdjacenciesOp adjs = del.augmentation(AdjacenciesOp.class);
Map<AdjacencyKey, Adjacency> adjMap = adjs != null ? adjs.getAdjacency() : null;
if (vpnInstOp != null && adjMap != null && adjMap.size() > 0) {
/*
* When a VPN Interface is removed by FibManager (aka VrfEntryListener and its cohorts),
* one adjacency or two adjacency (in case of dual-stack)
* for that VPN Interface will be hanging around along with that
* VPN Interface. That adjacency could be primary (or) non-primary.
* If its a primary adjacency, then a prefix-to-interface entry will be available for the
* same. If its a non-primary adjacency, then a prefix-to-interface entry will not be
* available for the same, instead we will have vpn-to-extraroutes filled in for them.
*
* Here we try to remove prefix-to-interface entry for pending adjacency in the deleted
* vpnInterface. More importantly, we also update the vpnInstanceOpData by removing this
* vpnInterface from it.
*/
List<Prefixes> prefixToInterface = new ArrayList<>();
for (Adjacency adjacency : adjs.getAdjacency().values()) {
List<Prefixes> prefixToInterfaceLocal = new ArrayList<>();
Optional<Prefixes> prefix = operTx.read(VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(), VpnUtil.getIpPrefix(adjacency.getIpAddress()))).get();
if (prefix.isPresent()) {
prefixToInterfaceLocal.add(prefix.get());
}
if (prefixToInterfaceLocal.isEmpty() && adjacency.getNextHopIpList() != null) {
for (String nh : adjacency.getNextHopIpList()) {
prefix = operTx.read(VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(), VpnUtil.getIpPrefix(nh))).get();
if (prefix.isPresent()) {
prefixToInterfaceLocal.add(prefix.get());
}
}
}
if (!prefixToInterfaceLocal.isEmpty()) {
prefixToInterface.addAll(prefixToInterfaceLocal);
}
}
/*
* In VPN Migration scenarios, there is a race condition where we use the new DPNID
* for the migrated VM instead of old DPNID because when we read prefix-to-interface to cleanup
* old DPNID, we actually get the new DPNID.
*
* More dangerously, we tend to alter the new prefix-to-interface which should be retained intac
* for the migration to succeed in L3VPN. As a workaround, here we are going to use the dpnId in
* the deleted vpnInterface itself instead of tinkering with the prefix-to-interface. Further we
* will tinker prefix-to-interface only when are damn sure if its value matches our
* deleted vpnInterface.
*
*/
for (Prefixes pref : prefixToInterface) {
if (VpnUtil.isMatchedPrefixToInterface(pref, del)) {
operTx.delete(VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(), pref.getIpAddress()));
}
}
}
if (del.getDpnId() != null) {
vpnFootprintService.updateVpnToDpnMapping(del.getDpnId(), del.getVpnInstanceName(), rd, interfaceName, null, /*ipAddressSourceValuePair*/
false);
}
LOG.info("postProcessVpnInterfaceRemoval: Removed vpn operational data and updated vpn footprint" + " for interface {} on dpn {} vpn {}", interfaceName, del.getDpnId(), vpnName);
} else {
LOG.error("postProcessVpnInterfaceRemoval: rd not retrievable as vpninstancetovpnid for vpn {}" + " is absent, trying rd as {}. interface {} dpn {}", vpnName, vpnName, interfaceName, del.getDpnId());
}
notifyTaskIfRequired(interfaceName);
} catch (InterruptedException | ExecutionException e) {
LOG.error("postProcessVpnInterfaceRemoval: Failed to read data store for interface {} vpn {}", interfaceName, vpnName);
}
}
use of org.opendaylight.mdsal.binding.util.Datastore.CONFIGURATION in project netvirt by opendaylight.
the class TunnelEndPointChangeListener method add.
@Override
public void add(InstanceIdentifier<TunnelEndPoints> key, TunnelEndPoints tep) {
Uint64 dpnId = key.firstIdentifierOf(DPNTEPsInfo.class).firstKeyOf(DPNTEPsInfo.class).getDPNID();
if (Uint64.ZERO.equals(dpnId)) {
LOG.warn("add: Invalid DPN id for TEP {}", tep.getInterfaceName());
return;
}
List<VpnInstance> vpnInstances = VpnHelper.getAllVpnInstances(broker);
if (vpnInstances == null || vpnInstances.isEmpty()) {
LOG.warn("add: dpnId: {}: tep: {}: No VPN instances defined", dpnId, tep.getInterfaceName());
return;
}
for (VpnInstance vpnInstance : vpnInstances) {
final String vpnName = vpnInstance.getVpnInstanceName();
final Uint32 vpnId = vpnUtil.getVpnId(vpnName);
LOG.info("add: Handling TEP {} add for VPN instance {}", tep.getInterfaceName(), vpnName);
final String primaryRd = vpnUtil.getPrimaryRd(vpnName);
if (!vpnUtil.isVpnPendingDelete(primaryRd)) {
List<VpnInterfaces> vpnInterfaces = vpnUtil.getDpnVpnInterfaces(vpnInstance, dpnId);
if (vpnInterfaces != null) {
for (VpnInterfaces vpnInterface : vpnInterfaces) {
String vpnInterfaceName = vpnInterface.getInterfaceName();
jobCoordinator.enqueueJob("VPNINTERFACE-" + vpnInterfaceName, () -> {
final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface interfaceState = InterfaceUtils.getInterfaceStateFromOperDS(broker, vpnInterfaceName);
if (interfaceState == null) {
LOG.debug("add: Cannot retrieve interfaceState for vpnInterfaceName {}, " + "cannot generate lPortTag and process adjacencies", vpnInterfaceName);
return Collections.emptyList();
}
final int lPortTag = interfaceState.getIfIndex();
List<ListenableFuture<?>> futures = new ArrayList<>();
Set<String> prefixesForRefreshFib = new HashSet<>();
ListenableFuture<?> writeConfigFuture = txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, writeConfigTxn -> futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL, writeOperTxn -> futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, writeInvTxn -> vpnInterfaceManager.processVpnInterfaceAdjacencies(dpnId, lPortTag, vpnName, primaryRd, vpnInterfaceName, vpnId, writeConfigTxn, writeOperTxn, writeInvTxn, interfaceState, prefixesForRefreshFib))))));
Futures.addCallback(writeConfigFuture, new FutureCallback<Object>() {
@Override
public void onSuccess(Object voidObj) {
prefixesForRefreshFib.forEach(prefix -> {
fibManager.refreshVrfEntry(primaryRd, prefix);
});
}
@Override
public void onFailure(Throwable throwable) {
LOG.debug("addVpnInterface: write Tx config execution failed", throwable);
}
}, MoreExecutors.directExecutor());
futures.add(writeConfigFuture);
LOG.trace("add: Handled TEP {} add for VPN instance {} VPN interface {}", tep.getInterfaceName(), vpnName, vpnInterfaceName);
return futures;
});
}
}
} else {
LOG.error("add: Ignoring addition of tunnel interface {} dpn {} for vpnInstance {} with primaryRd {}," + " as the VPN is already marked for deletion", tep.getInterfaceName(), dpnId, vpnName, primaryRd);
}
}
}
use of org.opendaylight.mdsal.binding.util.Datastore.CONFIGURATION in project netvirt by opendaylight.
the class InterfaceStateChangeListener method update.
// TODO Clean up the exception handling
@SuppressWarnings("checkstyle:IllegalCatch")
@Override
public void update(InstanceIdentifier<Interface> identifier, Interface original, Interface update) {
final String ifName = update.getName();
try {
if (update.getIfIndex() == null) {
return;
}
if (L2vlan.class.equals(update.getType())) {
LOG.info("VPN Interface update event - intfName {} from InterfaceStateChangeListener", update.getName());
jobCoordinator.enqueueJob("VPNINTERFACE-" + ifName, () -> {
List<ListenableFuture<?>> futures = new ArrayList<>(3);
futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL, writeOperTxn -> {
// map of prefix and vpn name used, as entry in prefix-to-interface datastore
// is prerequisite for refresh Fib to avoid race condition leading to missing remote
// next hop in bucket actions on bgp-vpn delete
Map<String, Set<String>> mapOfRdAndPrefixesForRefreshFib = new HashMap<>();
ListenableFuture<?> configTxFuture = txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, writeConfigTxn -> futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, writeInvTxn -> {
final VpnInterface vpnIf = vpnUtil.getConfiguredVpnInterface(ifName);
if (vpnIf != null) {
final int ifIndex = update.getIfIndex();
Uint64 dpnId;
try {
dpnId = InterfaceUtils.getDpIdFromInterface(update);
} catch (Exception e) {
LOG.error("remove: Unable to retrieve dpnId for interface {}", ifName, e);
return;
}
IntfTransitionState state = getTransitionState(original.getOperStatus(), update.getOperStatus());
if (state.equals(IntfTransitionState.STATE_IGNORE)) {
LOG.info("InterfaceStateChangeListener: Interface {} state " + "original {}" + "updated {} not handled", ifName, original.getOperStatus(), update.getOperStatus());
return;
}
LOG.error("InterfaceStateChangeListener- Processing ifState {} " + "update event " + "with dpnId {} operstate {}", ifName, dpnId, update.getOperStatus());
if (state.equals(IntfTransitionState.STATE_UP) && vpnIf.getVpnInstanceNames() != null) {
for (VpnInstanceNames vpnInterfaceVpnInstance : vpnIf.getVpnInstanceNames().values()) {
String vpnName = vpnInterfaceVpnInstance.getVpnName();
String primaryRd = vpnUtil.getPrimaryRd(vpnName);
Set<String> prefixes = new HashSet<>();
if (!vpnInterfaceManager.isVpnInstanceReady(vpnName)) {
LOG.error("VPN Interface update event - intfName {} " + "onto vpnName {} running oper-driven UP, " + "VpnInstance not ready, holding on", vpnIf.getName(), vpnName);
} else if (vpnUtil.isVpnPendingDelete(primaryRd)) {
LOG.error("update: Ignoring UP event for vpnInterface " + "{}, as vpnInstance {} with primaryRd {} is " + "already marked for deletion ", vpnIf.getName(), vpnName, primaryRd);
} else {
vpnInterfaceManager.processVpnInterfaceUp(dpnId, vpnIf, primaryRd, ifIndex, true, writeConfigTxn, writeOperTxn, writeInvTxn, update, vpnName, prefixes);
mapOfRdAndPrefixesForRefreshFib.put(primaryRd, prefixes);
}
}
} else if (state.equals(IntfTransitionState.STATE_DOWN) && vpnIf.getVpnInstanceNames() != null) {
for (VpnInstanceNames vpnInterfaceVpnInstance : vpnIf.getVpnInstanceNames().values()) {
String vpnName = vpnInterfaceVpnInstance.getVpnName();
LOG.info("VPN Interface update event - intfName {} " + " onto vpnName {} running oper-driven DOWN", vpnIf.getName(), vpnName);
Optional<VpnInterfaceOpDataEntry> optVpnInterface = vpnUtil.getVpnInterfaceOpDataEntry(vpnIf.getName(), vpnName);
if (optVpnInterface.isPresent()) {
VpnInterfaceOpDataEntry vpnOpInterface = optVpnInterface.get();
vpnInterfaceManager.processVpnInterfaceDown(dpnId, vpnIf.getName(), ifIndex, update.getPhysAddress().getValue(), vpnOpInterface, true, writeConfigTxn, writeOperTxn, writeInvTxn);
} else {
LOG.error("InterfaceStateChangeListener Update DOWN - " + " vpnInterface {}not available, ignoring event", vpnIf.getName());
continue;
}
}
}
} else {
LOG.debug("Interface {} is not a vpninterface, ignoring.", ifName);
}
})));
Futures.addCallback(configTxFuture, new VpnInterfaceCallBackHandler(mapOfRdAndPrefixesForRefreshFib), MoreExecutors.directExecutor());
futures.add(configTxFuture);
}));
return futures;
});
}
} catch (Exception e) {
LOG.error("Exception observed in handling updation of VPN Interface {}. ", update.getName(), e);
}
}
Aggregations