use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev200120.routers.Router in project netvirt by opendaylight.
the class VpnInterfaceManager method createFibEntryForRouterInterface.
protected void createFibEntryForRouterInterface(String primaryRd, VpnInterface vpnInterface, String interfaceName, TypedWriteTransaction<Configuration> writeConfigTxn, String vpnName) {
if (vpnInterface == null) {
return;
}
List<Adjacency> adjs = vpnUtil.getAdjacenciesForVpnInterfaceFromConfig(interfaceName);
if (adjs == null) {
LOG.error("createFibEntryForRouterInterface: VPN Interface {} of router addition failed as adjacencies for" + " this vpn interface could not be obtained. vpn {}", interfaceName, vpnName);
return;
}
for (Adjacency adj : adjs) {
if (adj.getAdjacencyType() == AdjacencyType.PrimaryAdjacency) {
String primaryInterfaceIp = adj.getIpAddress();
String macAddress = adj.getMacAddress();
String prefix = VpnUtil.getIpPrefix(primaryInterfaceIp);
Uint32 label = vpnUtil.getUniqueId(VpnConstants.VPN_IDPOOL_NAME, VpnUtil.getNextHopLabelKey(primaryRd, prefix));
if (label.longValue() == VpnConstants.INVALID_LABEL) {
LOG.error("createFibEntryForRouterInterface: Unable to retrieve label for vpn pool {}, " + "vpninterface {}, vpn {}, rd {}", VpnConstants.VPN_IDPOOL_NAME, interfaceName, vpnName, primaryRd);
return;
}
RouterInterface routerInt = new RouterInterfaceBuilder().setUuid(vpnName).setIpAddress(primaryInterfaceIp).setMacAddress(macAddress).build();
fibManager.addFibEntryForRouterInterface(primaryRd, prefix, routerInt, label, writeConfigTxn);
LOG.info("createFibEntryForRouterInterface: Router interface {} for vpn {} rd {} prefix {} label {}" + " macAddress {} processed successfully;", interfaceName, vpnName, primaryRd, prefix, label, macAddress);
} else {
LOG.error("createFibEntryForRouterInterface: VPN Interface {} of router addition failed as primary" + " adjacency for this vpn interface could not be obtained. rd {} vpnName {}", interfaceName, primaryRd, vpnName);
}
}
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev200120.routers.Router 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.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev200120.routers.Router in project netvirt by opendaylight.
the class VpnInterfaceManager method handleVpnInstanceUpdateForVpnInterface.
private boolean handleVpnInstanceUpdateForVpnInterface(InstanceIdentifier<VpnInterface> identifier, VpnInterface original, VpnInterface update, List<ListenableFuture<?>> futures) {
boolean isVpnInstanceUpdate = false;
final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class);
final String interfaceName = key.getName();
List<String> oldVpnList = VpnUtil.getVpnListForVpnInterface(original);
List<String> oldVpnListCopy = new ArrayList<>();
oldVpnListCopy.addAll(oldVpnList);
List<String> newVpnList = VpnUtil.getVpnListForVpnInterface(update);
List<String> newVpnListCopy = new ArrayList<>();
newVpnListCopy.addAll(newVpnList);
oldVpnList.removeAll(newVpnList);
newVpnList.removeAll(oldVpnListCopy);
// This block will execute only on if there is a change in the VPN Instance.
if (!oldVpnList.isEmpty() || !newVpnList.isEmpty()) {
/*
* Internet BGP-VPN Instance update with single router:
* ====================================================
* In this case single VPN Interface will be part of maximum 2 VPN Instance only.
* 1st VPN Instance : router VPN or external BGP-VPN.
* 2nd VPN Instance : Internet BGP-VPN(router-gw update/delete) for public network access.
*
* VPN Instance UPDATE:
* oldVpnList = 0 and newVpnList = 1 (Internet BGP-VPN)
* oldVpnList = 1 and newVpnList = 0 (Internet BGP-VPN)
*
* External BGP-VPN Instance update with single router:
* ====================================================
* In this case single VPN interface will be part of maximum 1 VPN Instance only.
*
* Updated VPN Instance will be always either internal router VPN to
* external BGP-VPN or external BGP-VPN to internal router VPN swap.
*
* VPN Instance UPDATE:
* oldVpnList = 1 and newVpnList = 1 (router VPN to Ext-BGPVPN)
* oldVpnList = 1 and newVpnList = 1 (Ext-BGPVPN to router VPN)
*
* Dual Router VPN Instance Update:
* ================================
* In this case single VPN interface will be part of maximum 3 VPN Instance only.
*
* 1st VPN Instance : router VPN or external BGP-VPN-1.
* 2nd VPN Instance : router VPN or external BGP-VPN-2.
* 3rd VPN Instance : Internet BGP-VPN(router-gw update/delete) for public network access.
*
* Dual Router --> Associated with common external BGP-VPN Instance.
* 1st router and 2nd router are getting associated with single External BGP-VPN
* 1) add 1st router to external bgpvpn --> oldVpnList=1, newVpnList=1;
* 2) add 2nd router to the same external bgpvpn --> oldVpnList=1, newVpnList=0
* In this case, we need to call removeVpnInterfaceCall() followed by addVpnInterfaceCall()
*
*
*/
isVpnInstanceUpdate = true;
if (VpnUtil.isDualRouterVpnUpdate(oldVpnListCopy, newVpnListCopy)) {
if ((oldVpnListCopy.size() == 2 || oldVpnListCopy.size() == 3) && oldVpnList.size() == 1 && newVpnList.isEmpty()) {
// Identify the external BGP-VPN Instance and pass that value as newVpnList
List<String> externalBgpVpnList = new ArrayList<>();
for (String newVpnName : newVpnListCopy) {
String primaryRd = vpnUtil.getPrimaryRd(newVpnName);
VpnInstanceOpDataEntry vpnInstanceOpDataEntry = vpnUtil.getVpnInstanceOpData(primaryRd);
if (vpnInstanceOpDataEntry.getBgpvpnType() == VpnInstanceOpDataEntry.BgpvpnType.BGPVPN) {
externalBgpVpnList.add(newVpnName);
break;
}
}
// This call will execute removeVpnInterfaceCall() followed by addVpnInterfaceCall()
updateVpnInstanceChange(identifier, interfaceName, original, update, oldVpnList, externalBgpVpnList, oldVpnListCopy, futures);
} else if ((oldVpnListCopy.size() == 2 || oldVpnListCopy.size() == 3) && oldVpnList.isEmpty() && newVpnList.size() == 1) {
// Identify the router VPN Instance and pass that value as oldVpnList
List<String> routerVpnList = new ArrayList<>();
for (String newVpnName : newVpnListCopy) {
String primaryRd = vpnUtil.getPrimaryRd(newVpnName);
VpnInstanceOpDataEntry vpnInstanceOpDataEntry = vpnUtil.getVpnInstanceOpData(primaryRd);
if (vpnInstanceOpDataEntry.getBgpvpnType() == VpnInstanceOpDataEntry.BgpvpnType.BGPVPN) {
routerVpnList.add(newVpnName);
break;
}
}
// This call will execute removeVpnInterfaceCall() followed by addVpnInterfaceCall()
updateVpnInstanceChange(identifier, interfaceName, original, update, routerVpnList, newVpnList, oldVpnListCopy, futures);
} else {
// Handle remaining use cases.
updateVpnInstanceChange(identifier, interfaceName, original, update, oldVpnList, newVpnList, oldVpnListCopy, futures);
}
} else {
updateVpnInstanceChange(identifier, interfaceName, original, update, oldVpnList, newVpnList, oldVpnListCopy, futures);
}
}
return isVpnInstanceUpdate;
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev200120.routers.Router in project netvirt by opendaylight.
the class VpnInterfaceManager method deleteFibEntryForRouterInterface.
protected void deleteFibEntryForRouterInterface(VpnInterface vpnInterface, TypedWriteTransaction<Configuration> writeConfigTxn, String vpnName) {
Adjacencies adjs = vpnInterface.augmentation(Adjacencies.class);
String rd = vpnUtil.getVpnRd(vpnName);
if (adjs != null) {
Map<AdjacencyKey, Adjacency> keyAdjacencyMap = adjs.nonnullAdjacency();
for (Adjacency adj : keyAdjacencyMap.values()) {
if (adj.getAdjacencyType() == AdjacencyType.PrimaryAdjacency) {
String primaryInterfaceIp = adj.getIpAddress();
String prefix = VpnUtil.getIpPrefix(primaryInterfaceIp);
fibManager.removeFibEntry(rd, prefix, null, writeConfigTxn);
LOG.info("deleteFibEntryForRouterInterface: FIB for router interface {} deleted for vpn {} rd {}" + " prefix {}", vpnInterface.getName(), vpnName, rd, prefix);
}
}
} else {
LOG.error("deleteFibEntryForRouterInterface: Adjacencies for vpninterface {} is null, rd: {}", vpnInterface.getName(), rd);
}
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev200120.routers.Router in project netvirt by opendaylight.
the class VpnManagerImpl method addArpResponderFlowsToExternalNetworkIps.
@Override
public void addArpResponderFlowsToExternalNetworkIps(String id, Collection<String> fixedIps, String macAddress, Uint64 dpnId, Uuid extNetworkId) {
if (dpnId == null || Uint64.ZERO.equals(dpnId)) {
LOG.warn("Failed to install arp responder flows for router {}. DPN id is missing.", id);
return;
}
String extInterfaceName = elanService.getExternalElanInterface(extNetworkId.getValue(), dpnId);
if (extInterfaceName != null) {
doAddArpResponderFlowsToExternalNetworkIps(id, fixedIps, macAddress, dpnId, extInterfaceName);
return;
}
LOG.warn("Failed to install responder flows for {}. No external interface found for DPN id {}", id, dpnId);
if (!upgradeState.isUpgradeInProgress()) {
return;
}
// The following through the end of the function deals with an upgrade scenario where the neutron configuration
// is restored before the OVS switches reconnect. In such a case, the elan-dpn-interfaces entries will be
// missing from the operational data store. In order to mitigate this we use DataTreeEventCallbackRegistrar
// to wait for the exact operational md-sal object we need to contain the external interface we need.
LOG.info("Upgrade in process, waiting for an external interface to appear on dpn {} for elan {}", dpnId, extNetworkId.getValue());
InstanceIdentifier<DpnInterfaces> dpnInterfacesIid = elanService.getElanDpnInterfaceOperationalDataPath(extNetworkId.getValue(), dpnId);
eventCallbacks.onAddOrUpdate(LogicalDatastoreType.OPERATIONAL, dpnInterfacesIid, (unused, alsoUnused) -> {
LOG.info("Reattempting write of arp responder for external interfaces for external network {}", extNetworkId);
DpnInterfaces dpnInterfaces = elanService.getElanInterfaceInfoByElanDpn(extNetworkId.getValue(), dpnId);
if (dpnInterfaces == null) {
LOG.error("Could not retrieve DpnInterfaces for {}, {}", extNetworkId.getValue(), dpnId);
return DataTreeEventCallbackRegistrar.NextAction.UNREGISTER;
}
String extIfc = null;
@Nullable List<String> interfaces = dpnInterfaces.getInterfaces();
if (interfaces != null) {
for (String dpnInterface : interfaces) {
if (interfaceManager.isExternalInterface(dpnInterface)) {
extIfc = dpnInterface;
break;
}
}
}
if (extIfc == null) {
if (upgradeState.isUpgradeInProgress()) {
LOG.info("External interface not found yet in elan {} on dpn {}, keep waiting", extNetworkId.getValue(), dpnInterfaces);
return DataTreeEventCallbackRegistrar.NextAction.CALL_AGAIN;
} else {
return DataTreeEventCallbackRegistrar.NextAction.UNREGISTER;
}
}
final String extIfcFinal = extIfc;
doAddArpResponderFlowsToExternalNetworkIps(id, fixedIps, macAddress, dpnId, extIfcFinal);
return DataTreeEventCallbackRegistrar.NextAction.UNREGISTER;
});
}
Aggregations