use of org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.interfaces.VpnInterface in project netvirt by opendaylight.
the class VpnInterfaceManager method removeVpnInterfaceFromVpn.
@SuppressFBWarnings("DLS_DEAD_LOCAL_STORE")
private void removeVpnInterfaceFromVpn(final InstanceIdentifier<VpnInterface> identifier, final VpnInterface vpnInterface, final String vpnName, final String interfaceName, final Interface interfaceState) {
LOG.info("remove: VPN Interface remove event - intfName {} vpn {} dpn {}", vpnInterface.getName(), vpnName, vpnInterface.getDpnId());
removeInterfaceFromUnprocessedList(identifier, vpnInterface);
jobCoordinator.enqueueJob("VPNINTERFACE-" + interfaceName, () -> {
List<ListenableFuture<?>> futures = new ArrayList<>(3);
ListenableFuture<?> configFuture = txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, writeConfigTxn -> futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL, writeOperTxn -> futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, writeInvTxn -> {
LOG.info("remove: - intfName {} onto vpnName {} running config-driven", interfaceName, vpnName);
Uint64 dpId;
int ifIndex;
String gwMacAddress;
InstanceIdentifier<VpnInterfaceOpDataEntry> interfaceId = VpnUtil.getVpnInterfaceOpDataEntryIdentifier(interfaceName, vpnName);
Optional<VpnInterfaceOpDataEntry> optVpnInterface;
try {
optVpnInterface = SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.OPERATIONAL, interfaceId);
} catch (InterruptedException | ExecutionException e) {
LOG.error("remove: Failed to read data store for interface {} vpn {}", interfaceName, vpnName);
return;
}
if (interfaceState != null) {
try {
dpId = InterfaceUtils.getDpIdFromInterface(interfaceState);
} catch (NumberFormatException | IllegalStateException e) {
LOG.error("remove: Unable to retrieve dpnId from interface operational" + " data store for interface {} on dpn {} for vpn {} Fetching" + " from vpn interface op data store. ", interfaceName, vpnInterface.getDpnId(), vpnName, e);
dpId = Uint64.ZERO;
}
ifIndex = interfaceState.getIfIndex();
gwMacAddress = interfaceState.getPhysAddress().getValue();
} else {
LOG.info("remove: Interface state not available for {}. Trying to fetch data" + " from vpn interface op.", interfaceName);
if (optVpnInterface.isPresent()) {
VpnInterfaceOpDataEntry vpnOpInterface = optVpnInterface.get();
dpId = vpnOpInterface.getDpnId();
ifIndex = vpnOpInterface.getLportTag().intValue();
gwMacAddress = vpnOpInterface.getGatewayMacAddress();
} else {
LOG.error("remove: Handling removal of VPN interface {} for vpn {} skipped" + " as interfaceState and vpn interface op is not" + " available", interfaceName, vpnName);
return;
}
}
processVpnInterfaceDown(dpId, interfaceName, ifIndex, gwMacAddress, optVpnInterface.isPresent() ? optVpnInterface.get() : null, false, writeConfigTxn, writeOperTxn, writeInvTxn);
LOG.info("remove: Removal of vpn interface {} on dpn {} for vpn {} processed " + "successfully", interfaceName, vpnInterface.getDpnId(), vpnName);
})))));
futures.add(configFuture);
Futures.addCallback(configFuture, new PostVpnInterfaceWorker(interfaceName, false, "Config"), MoreExecutors.directExecutor());
return futures;
}, DJC_MAX_RETRIES);
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.interfaces.VpnInterface in project netvirt by opendaylight.
the class VpnInterfaceManager method updateVpnInstanceChange.
private void updateVpnInstanceChange(InstanceIdentifier<VpnInterface> identifier, String interfaceName, VpnInterface original, VpnInterface update, List<String> oldVpnList, List<String> newVpnList, List<String> oldVpnListCopy, List<ListenableFuture<?>> futures) {
final Adjacencies origAdjs = original.augmentation(Adjacencies.class);
final List<Adjacency> oldAdjs = origAdjs != null && origAdjs.getAdjacency() != null ? new ArrayList<>(origAdjs.getAdjacency().values()) : new ArrayList<>();
final Adjacencies updateAdjs = update.augmentation(Adjacencies.class);
final List<Adjacency> newAdjs = updateAdjs != null && updateAdjs.getAdjacency() != null ? new ArrayList<>(updateAdjs.getAdjacency().values()) : new ArrayList<>();
boolean isOldVpnRemoveCallExecuted = false;
for (String oldVpnName : oldVpnList) {
LOG.info("updateVpnInstanceChange: VPN Interface update event - intfName {} " + "remove from vpnName {} ", interfaceName, oldVpnName);
removeVpnInterfaceCall(identifier, original, oldVpnName, interfaceName);
LOG.info("updateVpnInstanceChange: Processed Remove for update on VPNInterface" + " {} upon VPN update from old vpn {} to newVpn(s) {}", interfaceName, oldVpnName, newVpnList);
isOldVpnRemoveCallExecuted = true;
}
// Wait for previous interface bindings to be removed
if (isOldVpnRemoveCallExecuted && !newVpnList.isEmpty()) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
LOG.error("updateVpnInstanceChange: InterruptedException caught for interface {}", interfaceName, e);
}
}
for (String newVpnName : newVpnList) {
String primaryRd = vpnUtil.getPrimaryRd(newVpnName);
if (!vpnUtil.isVpnPendingDelete(primaryRd)) {
LOG.info("updateVpnInstanceChange: VPN Interface update event - intfName {} " + "onto vpnName {} ", interfaceName, newVpnName);
addVpnInterfaceCall(identifier, update, oldAdjs, newAdjs, newVpnName);
LOG.info("updateVpnInstanceChange: Processed Add for update on VPNInterface {}" + "from oldVpn(s) {} to newVpn {} ", interfaceName, oldVpnListCopy, newVpnName);
/* This block will execute only if V6 subnet is associated with internet BGP-VPN.
* Use Case:
* In Dual stack network, first V4 subnet only attached to router and router is associated
* with internet BGP-VPN(router-gw). At this point VPN interface is having only router vpn instance.
* Later V6 subnet is added to router, at this point existing VPN interface will get updated
* with Internet BGP-VPN instance(Note: Internet BGP-VPN Instance update in vpn interface
* is applicable for only on V6 subnet is added to router). newVpnList = Contains only Internet
* BGP-VPN Instance. So we required V6 primary adjacency info needs to be populated onto
* router VPN as well as Internet BGP-VPN.
*
* addVpnInterfaceCall() --> It will create V6 Adj onto Internet BGP-VPN only.
* updateVpnInstanceAdjChange() --> This method call is needed for second primary V6 Adj
* update in existing router VPN instance.
*/
if (vpnUtil.isBgpVpnInternet(newVpnName)) {
LOG.info("updateVpnInstanceChange: VPN Interface {} with new Adjacency {} in existing " + "VPN instance {}", interfaceName, newAdjs, original.getVpnInstanceNames());
updateVpnInstanceAdjChange(original, update, interfaceName, futures);
}
} else {
LOG.info("updateVpnInstanceChange: failed to Add for update on VPNInterface {} from oldVpn(s) {} to " + "newVpn {} as the new vpn does not exist in oper DS or it is in PENDING_DELETE state", interfaceName, oldVpnListCopy, newVpnName);
}
}
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.interfaces.VpnInterface in project netvirt by opendaylight.
the class VpnInterfaceManager method addVpnInterfaceCall.
private void addVpnInterfaceCall(final InstanceIdentifier<VpnInterface> identifier, final VpnInterface vpnInterface, final List<Adjacency> oldAdjs, final List<Adjacency> newAdjs, String vpnName) {
final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class);
final String interfaceName = key.getName();
if (!canHandleNewVpnInterface(identifier, vpnInterface, vpnName)) {
LOG.error("add: VpnInstance {} for vpnInterface {} not ready, holding on ", vpnName, vpnInterface.getName());
return;
}
InstanceIdentifier<VpnInterfaceOpDataEntry> vpnInterfaceOpIdentifier = VpnUtil.getVpnInterfaceOpDataEntryIdentifier(interfaceName, vpnName);
List<Adjacency> copyOldAdjs = null;
if (oldAdjs != null) {
copyOldAdjs = new ArrayList<>();
copyOldAdjs.addAll(oldAdjs);
}
List<Adjacency> copyNewAdjs = null;
if (newAdjs != null) {
copyNewAdjs = new ArrayList<>();
copyNewAdjs.addAll(newAdjs);
}
addVpnInterfaceToVpn(vpnInterfaceOpIdentifier, vpnInterface, copyOldAdjs, copyNewAdjs, identifier, vpnName);
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.interfaces.VpnInterface in project netvirt by opendaylight.
the class VpnInterfaceManager method updateVpnInterfaceOnTepDelete.
// TODO Clean up the exception handling
@SuppressWarnings("checkstyle:IllegalCatch")
public void updateVpnInterfaceOnTepDelete(VpnInterfaceOpDataEntry vpnInterface, StateTunnelList stateTunnelList, TypedWriteTransaction<Configuration> writeConfigTxn, TypedWriteTransaction<Operational> writeOperTxn) {
AdjacenciesOp adjacencies = vpnInterface.augmentation(AdjacenciesOp.class);
List<Adjacency> adjList = adjacencies != null ? new ArrayList<>(adjacencies.nonnullAdjacency().values()) : new ArrayList<>();
String prefix = null;
boolean isNextHopRemoveReqd = false;
String srcTepIp = stateTunnelList.getSrcInfo().getTepIp().stringValue();
Uint64 srcDpnId = Uint64.valueOf(stateTunnelList.getSrcInfo().getTepDeviceId()).intern();
String vpnName = vpnInterface.getVpnInstanceName();
Uint32 vpnId = vpnUtil.getVpnId(vpnName);
String primaryRd = vpnUtil.getVpnRd(vpnName);
if (adjList != null) {
List<Adjacency> value = new ArrayList<>();
LOG.info("updateVpnInterfaceOnTepDelete: AdjacencyList for interface {} on dpn {} vpn {} is {}", vpnInterface.getName(), vpnInterface.getDpnId(), vpnInterface.getVpnInstanceName(), adjList);
for (Adjacency adj : adjList) {
List<String> nhList = new ArrayList<>();
String rd = adj.getVrfId();
rd = rd != null ? rd : vpnName;
prefix = adj.getIpAddress();
List<String> nextHopList = adj.getNextHopIpList();
Uint32 label = adj.getLabel();
if (nextHopList != null && !nextHopList.isEmpty()) {
isNextHopRemoveReqd = true;
}
// Secondary adj nexthop will continue to point to primary adj IP address.
if (adj.getAdjacencyType() == AdjacencyType.PrimaryAdjacency) {
value.add(new AdjacencyBuilder(adj).setNextHopIpList(nhList).build());
} else {
Optional<VrfEntry> vrfEntryOptional = FibHelper.getVrfEntry(dataBroker, primaryRd, prefix);
if (!vrfEntryOptional.isPresent()) {
continue;
}
nhList = FibHelper.getNextHopListFromRoutePaths(vrfEntryOptional.get());
if (nhList.contains(srcTepIp)) {
nhList.remove(srcTepIp);
isNextHopRemoveReqd = true;
}
value.add(adj);
}
if (isNextHopRemoveReqd) {
updateLabelMapper(label, nhList);
LOG.info("updateVpnInterfaceOnTepDelete: Updated label mapper : label {} dpn {} prefix {}" + " nexthoplist {} vpn {} vpnid {} rd {} interface {}", label, srcDpnId, prefix, nhList, vpnName, vpnId, rd, vpnInterface.getName());
// Update the VRF entry with removed nextHop
fibManager.updateRoutePathForFibEntry(primaryRd, prefix, srcTepIp, label, false, writeConfigTxn);
// Get the list of VPN's importing this route(prefix) .
// Then update the VRF entry with nhList
List<VpnInstanceOpDataEntry> vpnsToImportRoute = vpnUtil.getVpnsImportingMyRoute(vpnName);
for (VpnInstanceOpDataEntry vpn : vpnsToImportRoute) {
String vpnRd = vpn.getVrfId();
if (vpnRd != null) {
fibManager.updateRoutePathForFibEntry(vpnRd, prefix, srcTepIp, label, false, writeConfigTxn);
LOG.info("updateVpnInterfaceOnTepDelete: Exported route with rd {} prefix {} nhList {}" + " label {} interface {} dpn {} from vpn {} to VPN {} vpnRd {}", rd, prefix, nhList, label, vpnInterface.getName(), srcDpnId, vpnName, vpn.getVpnInstanceName(), vpnRd);
}
}
// Withdraw prefix from BGP only for external vpn.
try {
if (!rd.equalsIgnoreCase(vpnName)) {
bgpManager.withdrawPrefix(rd, prefix);
}
LOG.info("updateVpnInterfaceOnTepDelete: Withdrawn rd {} prefix {} nhList {} label {}" + " for interface {} on dpn {} vpn {}", rd, prefix, nhList, label, vpnInterface.getName(), srcDpnId, vpnName);
} catch (Exception ex) {
LOG.error("updateVpnInterfaceOnTepDelete: Exception when withdrawing prefix {} nh {} label {}" + " on rd {} for interface {} on dpn {} vpn {}", prefix, nhList, label, rd, vpnInterface.getName(), srcDpnId, vpnName, ex);
}
}
}
AdjacenciesOp aug = VpnUtil.getVpnInterfaceOpDataEntryAugmentation(value);
VpnInterfaceOpDataEntry opInterface = new VpnInterfaceOpDataEntryBuilder(vpnInterface).withKey(new VpnInterfaceOpDataEntryKey(vpnInterface.getName(), vpnName)).addAugmentation(aug).build();
InstanceIdentifier<VpnInterfaceOpDataEntry> interfaceId = VpnUtil.getVpnInterfaceOpDataEntryIdentifier(vpnInterface.getName(), vpnName);
writeOperTxn.mergeParentStructurePut(interfaceId, opInterface);
LOG.info("updateVpnInterfaceOnTepDelete: interface {} updated successully on tep delete on dpn {} vpn {}", vpnInterface.getName(), srcDpnId, vpnName);
}
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.interfaces.VpnInterface in project netvirt by opendaylight.
the class VpnInterfaceManager method updateVpnInterfacesForUnProcessAdjancencies.
public void updateVpnInterfacesForUnProcessAdjancencies(String vpnName) {
String primaryRd = vpnUtil.getVpnRd(vpnName);
VpnInstanceOpDataEntry vpnInstanceOpData = vpnUtil.getVpnInstanceOpData(primaryRd);
if (vpnInstanceOpData == null || vpnInstanceOpData.getVpnToDpnList() == null) {
return;
}
List<VpnToDpnList> vpnToDpnLists = new ArrayList<>(vpnInstanceOpData.getVpnToDpnList().values());
if (vpnToDpnLists == null || vpnToDpnLists.isEmpty()) {
return;
}
LOG.debug("Update the VpnInterfaces for Unprocessed Adjancencies for vpnName:{}", vpnName);
vpnToDpnLists.forEach(vpnToDpnList -> {
if (vpnToDpnList.getVpnInterfaces() == null) {
return;
}
vpnToDpnList.nonnullVpnInterfaces().values().forEach(vpnInterface -> {
try {
InstanceIdentifier<VpnInterfaceOpDataEntry> existingVpnInterfaceId = VpnUtil.getVpnInterfaceOpDataEntryIdentifier(vpnInterface.getInterfaceName(), vpnName);
Optional<VpnInterfaceOpDataEntry> vpnInterfaceOptional = SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.OPERATIONAL, existingVpnInterfaceId);
if (!vpnInterfaceOptional.isPresent()) {
return;
}
List<Adjacency> configVpnAdjacencies = vpnUtil.getAdjacenciesForVpnInterfaceFromConfig(vpnInterface.getInterfaceName());
if (configVpnAdjacencies == null) {
LOG.debug("There is no adjacency available for vpnInterface:{}", vpnInterface);
return;
}
List<Adjacency> operationVpnAdjacencies = new ArrayList<>(vpnInterfaceOptional.get().augmentation(AdjacenciesOp.class).nonnullAdjacency().values());
// Due to insufficient rds, some of the extra route wont get processed when it is added.
// The unprocessed adjacencies will be present in config vpn interface DS but will be missing
// in operational DS. These unprocessed adjacencies will be handled below.
// To obtain unprocessed adjacencies, filtering is done by which the missing adjacencies in
// operational DS are retrieved which is used to call addNewAdjToVpnInterface method.
configVpnAdjacencies.stream().filter(adjacency -> operationVpnAdjacencies.stream().noneMatch(operationalAdjacency -> Objects.equals(operationalAdjacency.getIpAddress(), adjacency.getIpAddress()))).forEach(adjacency -> {
LOG.debug("Processing the vpnInterface{} for the Ajacency:{}", vpnInterface, adjacency);
jobCoordinator.enqueueJob("VPNINTERFACE-" + vpnInterface.getInterfaceName(), () -> {
// if the oper tx goes in
if (vpnUtil.isAdjacencyEligibleToVpn(adjacency, vpnName)) {
List<ListenableFuture<?>> futures = new ArrayList<>();
futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL, operTx -> {
// 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<?> configTxFuture = txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, confTx -> addNewAdjToVpnInterface(existingVpnInterfaceId, primaryRd, adjacency, vpnInterfaceOptional.get().getDpnId(), operTx, confTx, confTx, prefixListForRefreshFib));
Futures.addCallback(configTxFuture, new VpnInterfaceCallBackHandler(primaryRd, prefixListForRefreshFib), MoreExecutors.directExecutor());
futures.add(configTxFuture);
}));
return futures;
} else {
return emptyList();
}
});
});
} catch (InterruptedException | ExecutionException e) {
LOG.error("updateVpnInterfacesForUnProcessAdjancencies: Failed to read data store for vpn {} rd {}", vpnName, primaryRd);
}
});
});
}
Aggregations