use of org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance 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 BigInteger dpId, VpnInterface vpnInterface, final String primaryRd, final int lportTag, boolean isInterfaceUp, WriteTransaction writeConfigTxn, WriteTransaction writeOperTxn, WriteTransaction writeInvTxn, Interface interfaceState, final String vpnName) {
final String interfaceName = vpnInterface.getName();
Optional<VpnInterfaceOpDataEntry> optOpVpnInterface = VpnUtil.getVpnInterfaceOpDataEntry(dataBroker, interfaceName, vpnName);
VpnInterfaceOpDataEntry opVpnInterface = optOpVpnInterface.isPresent() ? optOpVpnInterface.get() : null;
boolean isBgpVpnInternetVpn = VpnUtil.isBgpVpnInternet(dataBroker, vpnName);
if (!isInterfaceUp) {
LOG.info("processVpnInterfaceUp: Binding vpn service to interface {} onto dpn {} for vpn {}", interfaceName, dpId, vpnName);
long vpnId = VpnUtil.getVpnId(dataBroker, vpnName);
if (vpnId == VpnConstants.INVALID_ID) {
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 && !opVpnInterface.isScheduledForRemove()) {
String opVpnName = opVpnInterface.getVpnInstanceName();
String primaryInterfaceIp = null;
if (opVpnName.equals(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(dataBroker, 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(dataBroker, 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);
if (!isBgpVpnInternetVpn) {
VpnUtil.bindService(vpnName, interfaceName, dataBroker, false, /*isTunnelInterface*/
jobCoordinator);
}
LOG.info("processVpnInterfaceUp: Plumbed vpn interface {} onto dpn {} for vpn {}", interfaceName, dpId, vpnName);
if (interfaceManager.isExternalInterface(interfaceName)) {
processExternalVpnInterface(interfaceName, vpnName, vpnId, dpId, lportTag, writeInvTxn, 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(txRunner, 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);
if (!isBgpVpnInternetVpn) {
VpnUtil.bindService(vpnName, interfaceName, dataBroker, false, /*isTunnelInterface*/
jobCoordinator);
}
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, vpnId, dpId, lportTag, writeInvTxn, NwConstants.ADD_FLOW);
}
} else {
// 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 = VpnUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, path);
if (!optAdjacencies.isPresent()) {
LOG.trace("No config adjacencies present for vpninterface {}", vpnInterface);
return;
}
List<Adjacency> adjacencies = optAdjacencies.get().getAdjacency();
for (Adjacency adjacency : adjacencies) {
if (adjacency.getAdjacencyType() == AdjacencyType.PrimaryAdjacency) {
continue;
}
// if BGPVPN Internet, filter only IPv6 Adjacencies
if (isBgpVpnInternetVpn && !VpnUtil.isAdjacencyEligibleToVpnInternet(dataBroker, adjacency)) {
continue;
}
addNewAdjToVpnInterface(vpnInterfaceOpIdentifier, primaryRd, adjacency, dpId, writeOperTxn, writeConfigTxn);
}
}
}
use of org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance 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, VpnInterfaceKey.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.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance in project netvirt by opendaylight.
the class VpnInterfaceOpListener method postProcessVpnInterfaceRemoval.
private void postProcessVpnInterfaceRemoval(InstanceIdentifier<VpnInterfaceOpDataEntry> identifier, VpnInterfaceOpDataEntry del, WriteTransaction writeOperTxn) {
final VpnInterfaceOpDataEntryKey key = identifier.firstKeyOf(VpnInterfaceOpDataEntry.class, VpnInterfaceOpDataEntryKey.class);
String interfaceName = key.getName();
String vpnName = del.getVpnInstanceName();
LOG.info("postProcessVpnInterfaceRemoval: interface name {} vpnName {} dpn {}", interfaceName, vpnName, del.getDpnId());
// decrement the vpn interface count in Vpn Instance Op Data
Optional<VpnInstance> vpnInstance = VpnUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, VpnOperDsUtils.getVpnInstanceToVpnIdIdentifier(vpnName));
if (vpnInstance.isPresent()) {
String rd = null;
rd = vpnInstance.get().getVrfId();
VpnInstanceOpDataEntry vpnInstOp = VpnUtil.getVpnInstanceOpData(dataBroker, rd);
AdjacenciesOp adjs = del.getAugmentation(AdjacenciesOp.class);
List<Adjacency> adjList = adjs != null ? adjs.getAdjacency() : null;
if (vpnInstOp != null && adjList != null && adjList.size() > 0) {
/*
* When a VPN Interface is removed by FibManager (aka VrfEntryListener and its cohorts),
* one adjacency 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()) {
List<Prefixes> prefixToInterfaceLocal = new ArrayList<>();
Optional<Prefixes> prefix = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(), VpnUtil.getIpPrefix(adjacency.getIpAddress())));
if (prefix.isPresent()) {
prefixToInterfaceLocal.add(prefix.get());
}
if (prefixToInterfaceLocal.isEmpty()) {
for (String nh : adjacency.getNextHopIpList()) {
prefix = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(), VpnUtil.getIpPrefix(nh)));
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 (isMatchedPrefixToInterface(pref, del)) {
if (writeOperTxn != null) {
writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(), pref.getIpAddress()));
} else {
VpnUtil.delete(dataBroker, LogicalDatastoreType.OPERATIONAL, VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(), pref.getIpAddress()), VpnUtil.DEFAULT_CALLBACK);
}
}
}
}
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);
}
use of org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance in project netvirt by opendaylight.
the class VpnUtil method getVpnHandlingIpv4AssociatedWithInterface.
static Optional<List<String>> getVpnHandlingIpv4AssociatedWithInterface(DataBroker broker, String interfaceName) {
InstanceIdentifier<VpnInterface> interfaceId = getVpnInterfaceIdentifier(interfaceName);
Optional<List<String>> vpnOptional = Optional.absent();
Optional<VpnInterface> optConfiguredVpnInterface = read(broker, LogicalDatastoreType.CONFIGURATION, interfaceId);
if (optConfiguredVpnInterface.isPresent()) {
VpnInterface cfgVpnInterface = optConfiguredVpnInterface.get();
java.util.Optional<List<VpnInstanceNames>> optVpnInstanceList = java.util.Optional.ofNullable(cfgVpnInterface.getVpnInstanceNames());
if (optVpnInstanceList.isPresent()) {
List<String> vpnList = new ArrayList<>();
for (VpnInstanceNames vpnInstance : optVpnInstanceList.get()) {
if (vpnInstance.getAssociatedSubnetType().equals(AssociatedSubnetType.V6Subnet)) {
continue;
}
vpnList.add(vpnInstance.getVpnName());
}
vpnOptional = Optional.of(vpnList);
}
}
return vpnOptional;
}
use of org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance in project netvirt by opendaylight.
the class VpnUtil method getListOfRdsFromVpnInstance.
public static List<String> getListOfRdsFromVpnInstance(VpnInstance vpnInstance) {
VpnAfConfig vpnConfig = vpnInstance.getIpv4Family();
LOG.trace("vpnConfig {}", vpnConfig);
return vpnConfig.getRouteDistinguisher() != null ? new ArrayList<>(vpnConfig.getRouteDistinguisher()) : new ArrayList<>();
}
Aggregations