use of org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.bgpvpns.rev150903.bgpvpns.attributes.bgpvpns.Bgpvpn in project netvirt by opendaylight.
the class VpnUtil method isAdjacencyEligibleToVpnInternet.
public static boolean isAdjacencyEligibleToVpnInternet(DataBroker dataBroker, Adjacency adjacency) {
// returns true if BGPVPN Internet and adjacency is IPv6, false otherwise
boolean adjacencyEligible = true;
if (adjacency.getAdjacencyType() == AdjacencyType.ExtraRoute) {
if (FibHelper.isIpv6Prefix(adjacency.getIpAddress())) {
return adjacencyEligible;
}
return false;
} else if (adjacency.getSubnetId() == null) {
return adjacencyEligible;
}
Subnetmap sn = VpnUtil.getSubnetmapFromItsUuid(dataBroker, adjacency.getSubnetId());
if (sn != null && sn.getInternetVpnId() != null) {
adjacencyEligible = false;
}
return adjacencyEligible;
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.bgpvpns.rev150903.bgpvpns.attributes.bgpvpns.Bgpvpn 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.neutron.bgpvpns.rev150903.bgpvpns.attributes.bgpvpns.Bgpvpn in project netvirt by opendaylight.
the class VpnInterfaceManager method processVpnInterfaceUp.
// "Unconditional wait" and "Wait not in loop" wrt the VpnNotifyTask below - suppressing the FB violation -
// see comments below.
@SuppressFBWarnings({ "UW_UNCOND_WAIT", "WA_NOT_IN_LOOP" })
protected void processVpnInterfaceUp(final Uint64 dpId, VpnInterface vpnInterface, final String primaryRd, final int lportTag, boolean isInterfaceUp, TypedWriteTransaction<Configuration> writeConfigTxn, TypedWriteTransaction<Operational> writeOperTxn, TypedReadWriteTransaction<Configuration> writeInvTxn, Interface interfaceState, final String vpnName, Set<String> prefixListForRefreshFib) throws ExecutionException, InterruptedException {
final String interfaceName = vpnInterface.getName();
Optional<VpnInterfaceOpDataEntry> optOpVpnInterface = vpnUtil.getVpnInterfaceOpDataEntry(interfaceName, vpnName);
VpnInterfaceOpDataEntry opVpnInterface = optOpVpnInterface.isPresent() ? optOpVpnInterface.get() : null;
boolean isBgpVpnInternetVpn = vpnUtil.isBgpVpnInternet(vpnName);
if (!isInterfaceUp) {
LOG.info("processVpnInterfaceUp: Binding vpn service to interface {} onto dpn {} for vpn {}", interfaceName, dpId, vpnName);
Uint32 vpnId = vpnUtil.getVpnId(vpnName);
if (VpnConstants.INVALID_ID.equals(vpnId)) {
LOG.warn("processVpnInterfaceUp: VpnInstance to VPNId mapping not available for VpnName {}" + " processing vpninterface {} on dpn {}, bailing out now.", vpnName, interfaceName, dpId);
return;
}
boolean waitForVpnInterfaceOpRemoval = false;
if (opVpnInterface != null) {
String opVpnName = opVpnInterface.getVpnInstanceName();
String primaryInterfaceIp = null;
if (Objects.equals(opVpnName, vpnName)) {
// Please check if the primary VRF Entry does not exist for VPNInterface
// If so, we have to process ADD, as this might be a DPN Restart with Remove and Add triggered
// back to back
// However, if the primary VRF Entry for this VPNInterface exists, please continue bailing out !
List<Adjacency> adjs = vpnUtil.getAdjacenciesForVpnInterfaceFromConfig(interfaceName);
if (adjs == null) {
LOG.error("processVpnInterfaceUp: VPN Interface {} on dpn {} for vpn {} failed as adjacencies" + " for this vpn interface could not be obtained", interfaceName, dpId, vpnName);
return;
}
for (Adjacency adj : adjs) {
if (adj.getAdjacencyType() == AdjacencyType.PrimaryAdjacency) {
primaryInterfaceIp = adj.getIpAddress();
break;
}
}
if (primaryInterfaceIp == null) {
LOG.error("processVpnInterfaceUp: VPN Interface {} addition on dpn {} for vpn {} failed" + " as primary adjacency for this vpn interface could not be obtained", interfaceName, dpId, vpnName);
return;
}
// Get the rd of the vpn instance
VrfEntry vrf = vpnUtil.getVrfEntry(primaryRd, primaryInterfaceIp);
if (vrf != null) {
LOG.error("processVpnInterfaceUp: VPN Interface {} on dpn {} for vpn {} already provisioned ," + " bailing out from here.", interfaceName, dpId, vpnName);
return;
}
waitForVpnInterfaceOpRemoval = true;
} else {
LOG.error("processVpnInterfaceUp: vpn interface {} to go to configured vpn {} on dpn {}," + " but in operational vpn {}", interfaceName, vpnName, dpId, opVpnName);
}
}
if (!waitForVpnInterfaceOpRemoval) {
// Add the VPNInterface and quit
vpnFootprintService.updateVpnToDpnMapping(dpId, vpnName, primaryRd, interfaceName, null, /*ipAddressSourceValuePair*/
true);
processVpnInterfaceAdjacencies(dpId, lportTag, vpnName, primaryRd, interfaceName, vpnId, writeConfigTxn, writeOperTxn, writeInvTxn, interfaceState, prefixListForRefreshFib);
if (!isBgpVpnInternetVpn) {
vpnUtil.bindService(vpnName, interfaceName, false);
}
LOG.info("processVpnInterfaceUp: Plumbed vpn interface {} onto dpn {} for vpn {}", interfaceName, dpId, vpnName);
if (interfaceManager.isExternalInterface(interfaceName)) {
processExternalVpnInterface(interfaceName, vpnName, dpId, lportTag, NwConstants.ADD_FLOW);
}
return;
}
// FIB didn't get a chance yet to clean up this VPNInterface
// Let us give it a chance here !
LOG.info("processVpnInterfaceUp: Trying to add VPN Interface {} on dpn {} for vpn {}," + " but waiting for FIB to clean up! ", interfaceName, dpId, vpnName);
try {
Runnable notifyTask = new VpnNotifyTask();
synchronized (notifyTask) {
// Per FB's "Unconditional wait" violation, the code should really verify that the condition it
// intends to wait for is not already satisfied before calling wait. However the VpnNotifyTask is
// published here while holding the lock on it so this path will hit the wait before notify can be
// invoked.
vpnIntfMap.put(interfaceName, notifyTask);
try {
notifyTask.wait(VpnConstants.MAX_WAIT_TIME_IN_MILLISECONDS);
} catch (InterruptedException e) {
// Ignored
}
}
} finally {
vpnIntfMap.remove(interfaceName);
}
if (opVpnInterface != null) {
LOG.warn("processVpnInterfaceUp: VPN Interface {} removal on dpn {} for vpn {}" + " by FIB did not complete on time," + " bailing addition ...", interfaceName, dpId, vpnName);
vpnUtil.unsetScheduledToRemoveForVpnInterface(interfaceName);
return;
}
// VPNInterface got removed, proceed with Add
LOG.info("processVpnInterfaceUp: Continuing to plumb vpn interface {} onto dpn {} for vpn {}", interfaceName, dpId, vpnName);
vpnFootprintService.updateVpnToDpnMapping(dpId, vpnName, primaryRd, interfaceName, null, /*ipAddressSourceValuePair*/
true);
processVpnInterfaceAdjacencies(dpId, lportTag, vpnName, primaryRd, interfaceName, vpnId, writeConfigTxn, writeOperTxn, writeInvTxn, interfaceState, prefixListForRefreshFib);
if (!isBgpVpnInternetVpn) {
vpnUtil.bindService(vpnName, interfaceName, false);
}
LOG.info("processVpnInterfaceUp: Plumbed vpn interface {} onto dpn {} for vpn {} after waiting for" + " FIB to clean up", interfaceName, dpId, vpnName);
if (interfaceManager.isExternalInterface(interfaceName)) {
processExternalVpnInterface(interfaceName, vpnName, dpId, lportTag, NwConstants.ADD_FLOW);
}
} else {
try {
// Interface is retained in the DPN, but its Link Up.
// Advertise prefixes again for this interface to BGP
InstanceIdentifier<VpnInterface> identifier = VpnUtil.getVpnInterfaceIdentifier(vpnInterface.getName());
InstanceIdentifier<VpnInterfaceOpDataEntry> vpnInterfaceOpIdentifier = VpnUtil.getVpnInterfaceOpDataEntryIdentifier(interfaceName, vpnName);
advertiseAdjacenciesForVpnToBgp(primaryRd, dpId, vpnInterfaceOpIdentifier, vpnName, interfaceName);
// Perform similar operation as interface add event for extraroutes.
InstanceIdentifier<Adjacencies> path = identifier.augmentation(Adjacencies.class);
Optional<Adjacencies> optAdjacencies = SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION, path);
if (!optAdjacencies.isPresent()) {
LOG.trace("No config adjacencyKeyAdjacencyMap present for vpninterface {}", vpnInterface);
return;
}
Map<AdjacencyKey, Adjacency> adjacencyKeyAdjacencyMap = optAdjacencies.get().nonnullAdjacency();
for (Adjacency adjacency : adjacencyKeyAdjacencyMap.values()) {
if (adjacency.getAdjacencyType() == AdjacencyType.PrimaryAdjacency) {
continue;
}
// if BGPVPN Internet, filter only IPv6 Adjacencies
if (isBgpVpnInternetVpn && !vpnUtil.isAdjacencyEligibleToVpnInternet(adjacency)) {
continue;
}
addNewAdjToVpnInterface(vpnInterfaceOpIdentifier, primaryRd, adjacency, dpId, writeOperTxn, writeConfigTxn, writeInvTxn, prefixListForRefreshFib);
}
} catch (InterruptedException | ExecutionException e) {
LOG.error("processVpnInterfaceUp: Failed to read data store for interface {} vpn {} rd {} dpn {}", interfaceName, vpnName, primaryRd, dpId);
}
}
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.bgpvpns.rev150903.bgpvpns.attributes.bgpvpns.Bgpvpn in project netvirt by opendaylight.
the class SnatExternalRoutersListener method add.
@Override
@SuppressWarnings("checkstyle:IllegalCatch")
public void add(InstanceIdentifier<Routers> identifier, Routers routers) {
if (natMode != NatMode.Conntrack) {
return;
}
String routerName = routers.getRouterName();
if (upgradeState.isUpgradeInProgress()) {
LOG.warn("add event for ext-router {}, but upgrade is in progress.", routerName);
return;
}
LOG.info("add : external router event for {}", routerName);
Uint32 routerId = NatUtil.getVpnId(dataBroker, routerName);
NatUtil.createRouterIdsConfigDS(dataBroker, routerId, routerName);
Uuid bgpVpnUuid = NatUtil.getVpnForRouter(dataBroker, routerName);
if (bgpVpnUuid != null) {
// Router associated to BGPVPN, ignoring it.
return;
}
// Allocate Primary NAPTSwitch for this router
centralizedSwitchScheduler.scheduleCentralizedSwitch(routers);
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.bgpvpns.rev150903.bgpvpns.attributes.bgpvpns.Bgpvpn in project netvirt by opendaylight.
the class VpnUtil method updateVpnInstanceOpDataWithVpnType.
public void updateVpnInstanceOpDataWithVpnType(String vpnName, VpnInstance.BgpvpnType bgpvpnType, WriteTransaction writeOperTxn) {
VpnInstanceOpDataEntry vpnInstanceOpDataEntry = getVpnInstanceOpDataEntryFromVpnName(vpnName);
if (vpnInstanceOpDataEntry == null) {
LOG.error("updateVpnInstanceOpDataWithVpnType: VpnInstance {} with BGPVPN Type {} update Failed." + "Since vpnInstanceOpData is not yet ready.", vpnName, bgpvpnType);
return;
}
if (vpnInstanceOpDataEntry.getType() == VpnInstanceOpDataEntry.Type.L2) {
LOG.error("updateVpnInstanceOpDataWithVpnType: Unable to update the VpnInstance {} with BGPVPN Type {}." + "Since VPN type is L2 flavour. Do Nothing.", vpnName, bgpvpnType);
return;
}
synchronized (vpnName.intern()) {
VpnInstanceOpDataEntryBuilder builder = new VpnInstanceOpDataEntryBuilder().setVrfId(vpnInstanceOpDataEntry.getVrfId());
builder.setBgpvpnType(VpnInstanceOpDataEntry.BgpvpnType.forValue(bgpvpnType.getIntValue()));
InstanceIdentifier<VpnInstanceOpDataEntry> id = InstanceIdentifier.builder(VpnInstanceOpData.class).child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(vpnInstanceOpDataEntry.getVrfId())).build();
writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL, id, builder.build());
LOG.info("updateVpnInstanceOpDataWithVpnType: Successfully updated vpn-instance-op-data with BGPVPN type " + "{} for the Vpn {}", bgpvpnType, vpnName);
}
}
Aggregations