use of org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.adjacency.list.AdjacencyKey in project netvirt by opendaylight.
the class VpnInterfaceManager method removeAdjacenciesFromVpn.
private void removeAdjacenciesFromVpn(final Uint64 dpnId, final int lportTag, final String interfaceName, final String vpnName, final Uint32 vpnId, String gwMac, TypedWriteTransaction<Configuration> writeConfigTxn, TypedWriteTransaction<Operational> writeOperTxn, TypedReadWriteTransaction<Configuration> writeInvTxn) throws ExecutionException, InterruptedException {
// Read NextHops
try {
InstanceIdentifier<VpnInterfaceOpDataEntry> identifier = VpnUtil.getVpnInterfaceOpDataEntryIdentifier(interfaceName, vpnName);
Optional<VpnInterfaceOpDataEntry> vpnInterfaceOpDataEnteryOptional = SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.OPERATIONAL, identifier);
boolean isNonPrimaryAdjIp = false;
String primaryRd = vpnUtil.getVpnRd(vpnName);
LOG.info("removeAdjacenciesFromVpn: For interface {} on dpn {} RD recovered for vpn {} as rd {}", interfaceName, dpnId, vpnName, primaryRd);
if (!vpnInterfaceOpDataEnteryOptional.isPresent()) {
LOG.error("removeAdjacenciesFromVpn: VpnInterfaceOpDataEntry-Oper DS is absent for Interface {} " + "on vpn {} dpn {}", interfaceName, vpnName, dpnId);
return;
}
AdjacenciesOp adjacencies = vpnInterfaceOpDataEnteryOptional.get().augmentation(AdjacenciesOp.class);
if (adjacencies != null && adjacencies.getAdjacency() != null) {
Map<AdjacencyKey, Adjacency> nextHopsMap = adjacencies.nonnullAdjacency();
LOG.info("removeAdjacenciesFromVpn: NextHops for interface {} on dpn {} for vpn {} are {}", interfaceName, dpnId, vpnName, nextHopsMap);
for (Adjacency nextHop : nextHopsMap.values()) {
if (nextHop.isPhysNetworkFunc()) {
LOG.info("removeAdjacenciesFromVpn: Removing PNF FIB entry rd {} prefix {}", nextHop.getSubnetId().getValue(), nextHop.getIpAddress());
fibManager.removeFibEntry(nextHop.getSubnetId().getValue(), nextHop.getIpAddress(), null, null);
} else {
String rd = nextHop.getVrfId();
List<String> nhList;
if (nextHop.getAdjacencyType() != AdjacencyType.PrimaryAdjacency) {
nhList = getNextHopForNonPrimaryAdjacency(nextHop, vpnName, dpnId, interfaceName);
isNonPrimaryAdjIp = Boolean.TRUE;
} else {
// This is a primary adjacency
nhList = nextHop.getNextHopIpList() != null ? nextHop.getNextHopIpList() : emptyList();
removeGwMacAndArpResponderFlows(nextHop, vpnId, dpnId, lportTag, gwMac, vpnInterfaceOpDataEnteryOptional.get().getGatewayIpAddress(), interfaceName, writeInvTxn);
isNonPrimaryAdjIp = Boolean.FALSE;
}
if (!nhList.isEmpty()) {
if (Objects.equals(primaryRd, vpnName)) {
// this is an internal vpn - the rd is assigned to the vpn instance name;
// remove from FIB directly
nhList.forEach(removeAdjacencyFromInternalVpn(nextHop, vpnName, interfaceName, dpnId, writeConfigTxn, writeOperTxn));
} else {
removeAdjacencyFromBgpvpn(nextHop, nhList, vpnName, primaryRd, dpnId, rd, interfaceName, isNonPrimaryAdjIp, writeConfigTxn, writeOperTxn);
}
} else {
LOG.error("removeAdjacenciesFromVpn: nextHop empty for ip {} rd {} adjacencyType {}" + " interface {}", nextHop.getIpAddress(), rd, nextHop.getAdjacencyType().toString(), interfaceName);
bgpManager.withdrawPrefixIfPresent(rd, nextHop.getIpAddress());
fibManager.removeFibEntry(primaryRd, nextHop.getIpAddress(), null, writeConfigTxn);
}
}
String ip = nextHop.getIpAddress().split("/")[0];
LearntVpnVipToPort vpnVipToPort = vpnUtil.getLearntVpnVipToPort(vpnName, ip);
if (vpnVipToPort != null && vpnVipToPort.getPortName().equals(interfaceName)) {
vpnUtil.removeLearntVpnVipToPort(vpnName, ip, null);
LOG.info("removeAdjacenciesFromVpn: VpnInterfaceManager removed LearntVpnVipToPort entry" + " for Interface {} ip {} on dpn {} for vpn {}", vpnVipToPort.getPortName(), ip, dpnId, vpnName);
}
// Remove the MIP-IP from VpnPortIpToPort.
if (isNonPrimaryAdjIp) {
VpnPortipToPort persistedIp = vpnUtil.getVpnPortipToPort(vpnName, ip);
if (persistedIp != null && persistedIp.isLearntIp() && persistedIp.getPortName().equals(interfaceName)) {
VpnUtil.removeVpnPortFixedIpToPort(dataBroker, vpnName, ip, null);
LOG.info("removeAdjacenciesFromVpn: Learnt-IP: {} interface {} of vpn {} removed " + "from VpnPortipToPort", persistedIp.getPortFixedip(), persistedIp.getPortName(), vpnName);
}
}
VpnPortipToPort vpnPortipToPort = vpnUtil.getNeutronPortFromVpnPortFixedIp(vpnName, ip);
if (vpnPortipToPort != null) {
VpnUtil.removeVpnPortFixedIpToPort(dataBroker, vpnName, ip, null);
LOG.info("removeAdjacenciesFromVpn: VpnInterfaceManager removed vpnPortipToPort entry for " + "Interface {} ip {} on dpn {} for vpn {}", vpnPortipToPort.getPortName(), ip, dpnId, vpnName);
}
}
} else {
// this vpn interface has no more adjacency left, so clean up the vpn interface from Operational DS
LOG.info("removeAdjacenciesFromVpn: Vpn Interface {} on vpn {} dpn {} has no adjacencies." + " Removing it.", interfaceName, vpnName, dpnId);
writeOperTxn.delete(identifier);
}
} catch (InterruptedException | ExecutionException e) {
LOG.error("removeAdjacenciesFromVpn: Failed to read data store for interface {} dpn {} vpn {}", interfaceName, dpnId, vpnName);
}
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.adjacency.list.AdjacencyKey in project netvirt by opendaylight.
the class VpnInterfaceManager method updateVpnInterfaceOnTepAdd.
// TODO Clean up the exception handling
@SuppressWarnings("checkstyle:IllegalCatch")
public void updateVpnInterfaceOnTepAdd(VpnInterfaceOpDataEntry vpnInterface, StateTunnelList stateTunnelList, TypedWriteTransaction<Configuration> writeConfigTxn, TypedWriteTransaction<Operational> writeOperTxn) {
String srcTepIp = stateTunnelList.getSrcInfo().getTepIp().stringValue();
Uint64 srcDpnId = Uint64.valueOf(stateTunnelList.getSrcInfo().getTepDeviceId()).intern();
AdjacenciesOp adjacencies = vpnInterface.augmentation(AdjacenciesOp.class);
Map<AdjacencyKey, Adjacency> keyAdjacencyMap = adjacencies != null && adjacencies.getAdjacency() != null ? adjacencies.getAdjacency() : Collections.<AdjacencyKey, Adjacency>emptyMap();
if (keyAdjacencyMap.isEmpty()) {
LOG.trace("updateVpnInterfaceOnTepAdd: Adjacencies are empty for vpnInterface {} on dpn {}", vpnInterface, srcDpnId);
return;
}
String prefix = null;
List<Adjacency> value = new ArrayList<>();
boolean isFibNextHopAddReqd = false;
String vpnName = vpnInterface.getVpnInstanceName();
Uint32 vpnId = vpnUtil.getVpnId(vpnName);
String primaryRd = vpnUtil.getPrimaryRd(vpnName);
LOG.info("updateVpnInterfaceOnTepAdd: AdjacencyList for interface {} on dpn {} vpn {} is {}", vpnInterface.getName(), vpnInterface.getDpnId(), vpnInterface.getVpnInstanceName(), keyAdjacencyMap);
for (Adjacency adj : keyAdjacencyMap.values()) {
String rd = adj.getVrfId();
rd = rd != null ? rd : vpnName;
prefix = adj.getIpAddress();
Uint32 label = adj.getLabel();
List<String> nhList = Collections.singletonList(srcTepIp);
List<String> nextHopList = adj.getNextHopIpList();
// Secondary adj nexthop is already pointing to primary adj IP address.
if (adj.getAdjacencyType() == AdjacencyType.PrimaryAdjacency) {
value.add(new AdjacencyBuilder(adj).setNextHopIpList(nhList).build());
if (nextHopList != null && !nextHopList.isEmpty()) {
/* everything right already */
} else {
isFibNextHopAddReqd = true;
}
} else {
Optional<VrfEntry> vrfEntryOptional = FibHelper.getVrfEntry(dataBroker, primaryRd, prefix);
if (!vrfEntryOptional.isPresent()) {
continue;
}
nhList = FibHelper.getNextHopListFromRoutePaths(vrfEntryOptional.get());
if (!nhList.contains(srcTepIp)) {
nhList.add(srcTepIp);
isFibNextHopAddReqd = true;
}
value.add(adj);
}
if (isFibNextHopAddReqd) {
updateLabelMapper(label, nhList);
LOG.info("updateVpnInterfaceOnTepAdd: Updated label mapper : label {} dpn {} prefix {} nexthoplist {}" + " vpn {} vpnid {} rd {} interface {}", label, srcDpnId, prefix, nhList, vpnInterface.getVpnInstanceName(), vpnId, rd, vpnInterface.getName());
// Update the VRF entry with nextHop
fibManager.updateRoutePathForFibEntry(primaryRd, prefix, srcTepIp, label, true, 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, true, writeConfigTxn);
LOG.info("updateVpnInterfaceOnTepAdd: 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);
}
}
// since there is a nexthop change.
try {
if (!rd.equalsIgnoreCase(vpnName)) {
bgpManager.advertisePrefix(rd, null, /*macAddress*/
prefix, nhList, VrfEntry.EncapType.Mplsgre, label, Uint32.ZERO, /*evi*/
Uint32.ZERO, /*l2vni*/
null);
}
LOG.info("updateVpnInterfaceOnTepAdd: Advertised rd {} prefix {} nhList {} label {}" + " for interface {} on dpn {} vpn {}", rd, prefix, nhList, label, vpnInterface.getName(), srcDpnId, vpnName);
} catch (Exception ex) {
LOG.error("updateVpnInterfaceOnTepAdd: Exception when advertising 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("updateVpnInterfaceOnTepAdd: interface {} updated successully on tep add on dpn {} vpn {}", vpnInterface.getName(), srcDpnId, vpnName);
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.adjacency.list.AdjacencyKey in project netvirt by opendaylight.
the class VpnInterfaceManager method processVpnInterfaceAdjacencies.
@SuppressWarnings("checkstyle:IllegalCatch")
protected void processVpnInterfaceAdjacencies(Uint64 dpnId, final int lportTag, String vpnName, String primaryRd, String interfaceName, final Uint32 vpnId, TypedWriteTransaction<Configuration> writeConfigTxn, TypedWriteTransaction<Operational> writeOperTxn, TypedReadWriteTransaction<Configuration> writeInvTxn, Interface interfaceState, Set<String> prefixListForRefreshFib) throws ExecutionException, InterruptedException {
InstanceIdentifier<VpnInterface> identifier = VpnUtil.getVpnInterfaceIdentifier(interfaceName);
// Read NextHops
Optional<VpnInterface> vpnInteface = Optional.empty();
try {
vpnInteface = SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION, identifier);
} catch (InterruptedException | ExecutionException e) {
LOG.error("processVpnInterfaceAdjacencies: Failed to read data store for interface {} vpn {} rd {}" + "dpn {}", interfaceName, vpnName, primaryRd, dpnId);
}
Uuid intfnetworkUuid = null;
NetworkType networkType = null;
long segmentationId = -1L;
Adjacencies adjacencies = null;
if (vpnInteface.isPresent()) {
intfnetworkUuid = vpnInteface.get().getNetworkId();
networkType = vpnInteface.get().getNetworkType();
segmentationId = vpnInteface.get().getSegmentationId().toJava();
adjacencies = vpnInteface.get().augmentation(Adjacencies.class);
if (adjacencies == null) {
addVpnInterfaceToOperational(vpnName, interfaceName, dpnId, null, /*adjacencies*/
lportTag, null, /*gwMac*/
null, /*gatewayIp*/
writeOperTxn);
return;
}
}
// Get the rd of the vpn instance
String nextHopIp = null;
String gatewayIp = null;
try {
nextHopIp = InterfaceUtils.getEndpointIpAddressForDPN(dataBroker, dpnId);
} catch (Exception e) {
LOG.error("processVpnInterfaceAdjacencies: Unable to retrieve endpoint ip address for " + "dpnId {} for vpnInterface {} vpnName {}", dpnId, interfaceName, vpnName);
}
List<String> nhList = new ArrayList<>();
if (nextHopIp != null) {
nhList.add(nextHopIp);
LOG.debug("processVpnInterfaceAdjacencies: NextHop for interface {} on dpn {} in vpn {} is {}", interfaceName, dpnId, vpnName, nhList);
}
Optional<String> gwMac = Optional.empty();
String vpnInterfaceSubnetGwMacAddress = null;
VpnInstanceOpDataEntry vpnInstanceOpData = vpnUtil.getVpnInstanceOpData(primaryRd);
Uint32 l3vni = vpnInstanceOpData.getL3vni() != null ? vpnInstanceOpData.getL3vni() : Uint32.ZERO;
boolean isL3VpnOverVxLan = VpnUtil.isL3VpnOverVxLan(l3vni);
VrfEntry.EncapType encapType = isL3VpnOverVxLan ? VrfEntry.EncapType.Vxlan : VrfEntry.EncapType.Mplsgre;
VpnPopulator registeredPopulator = L3vpnRegistry.getRegisteredPopulator(encapType);
Map<AdjacencyKey, Adjacency> nextHopsMap = adjacencies != null ? adjacencies.getAdjacency() : Collections.<AdjacencyKey, Adjacency>emptyMap();
List<Adjacency> value = new ArrayList<>();
for (Adjacency nextHop : nextHopsMap.values()) {
String rd = primaryRd;
String nexthopIpValue = nextHop.getIpAddress().split("/")[0];
if (vpnInstanceOpData.getBgpvpnType() == VpnInstanceOpDataEntry.BgpvpnType.InternetBGPVPN && NWUtil.isIpv4Address(nexthopIpValue)) {
String prefix = nextHop.getIpAddress() == null ? "null" : VpnUtil.getIpPrefix(nextHop.getIpAddress());
LOG.debug("processVpnInterfaceAdjacencies: UnsupportedOperation : Not Adding prefix {} to interface {}" + " as InternetVpn has an IPV4 address {}", prefix, interfaceName, vpnName);
continue;
}
if (nextHop.getAdjacencyType() == AdjacencyType.PrimaryAdjacency) {
String prefix = VpnUtil.getIpPrefix(nextHop.getIpAddress());
Prefixes.PrefixCue prefixCue = nextHop.isPhysNetworkFunc() ? Prefixes.PrefixCue.PhysNetFunc : Prefixes.PrefixCue.None;
LOG.debug("processVpnInterfaceAdjacencies: Adding prefix {} to interface {} with nextHopsMap {} " + "on dpn {} for vpn {}", prefix, interfaceName, nhList, dpnId, vpnName);
Prefixes prefixes = intfnetworkUuid != null ? VpnUtil.getPrefixToInterface(dpnId, interfaceName, prefix, intfnetworkUuid, networkType, segmentationId, prefixCue) : VpnUtil.getPrefixToInterface(dpnId, interfaceName, prefix, prefixCue);
writeOperTxn.mergeParentStructureMerge(VpnUtil.getPrefixToInterfaceIdentifier(vpnUtil.getVpnId(vpnName), prefix), prefixes);
final Uuid subnetId = nextHop.getSubnetId();
gatewayIp = nextHop.getSubnetGatewayIp();
if (gatewayIp == null) {
Optional<String> gatewayIpOptional = vpnUtil.getVpnSubnetGatewayIp(subnetId);
if (gatewayIpOptional.isPresent()) {
gatewayIp = gatewayIpOptional.get();
}
}
if (gatewayIp != null) {
gwMac = getMacAddressForSubnetIp(vpnName, interfaceName, gatewayIp);
if (gwMac.isPresent()) {
// A valid mac-address is available for this subnet-gateway-ip
// Use this for programming ARP_RESPONDER table here. And save this
// info into vpnInterface operational, so it can used in VrfEntryProcessor
// to populate L3_GW_MAC_TABLE there.
arpResponderHandler.addArpResponderFlow(dpnId, lportTag, interfaceName, gatewayIp, gwMac.get());
vpnInterfaceSubnetGwMacAddress = gwMac.get();
} else {
// A valid mac-address is not available for this subnet-gateway-ip
// Use the connected-mac-address to configure ARP_RESPONDER Table.
// Save this connected-mac-address as gateway-mac-address for the
// VrfEntryProcessor to use this later to populate the L3_GW_MAC_TABLE.
gwMac = InterfaceUtils.getMacAddressFromInterfaceState(interfaceState);
if (gwMac.isPresent()) {
vpnUtil.setupGwMacIfExternalVpn(dpnId, interfaceName, vpnId, writeInvTxn, NwConstants.ADD_FLOW, gwMac.get());
arpResponderHandler.addArpResponderFlow(dpnId, lportTag, interfaceName, gatewayIp, gwMac.get());
} else {
LOG.error("processVpnInterfaceAdjacencies: Gateway MAC for subnet ID {} could not be " + "obtained, cannot create ARP responder flow for interface name {}, vpnName {}, " + "gwIp {}", subnetId, interfaceName, vpnName, gatewayIp);
}
}
} else {
LOG.warn("processVpnInterfaceAdjacencies: Gateway IP for subnet ID {} could not be obtained, " + "cannot create ARP responder flow for interface name {}, vpnName {}", subnetId, interfaceName, vpnName);
gwMac = InterfaceUtils.getMacAddressFromInterfaceState(interfaceState);
}
LOG.info("processVpnInterfaceAdjacencies: Added prefix {} to interface {} with nextHopsMap {} on dpn {}" + " for vpn {}", prefix, interfaceName, nhList, dpnId, vpnName);
} else {
// Extra route adjacency
String prefix = VpnUtil.getIpPrefix(nextHop.getIpAddress());
String vpnPrefixKey = VpnUtil.getVpnNamePrefixKey(vpnName, prefix);
// FIXME: separate this out somehow?
final ReentrantLock lock = JvmGlobalLocks.getLockForString(vpnPrefixKey);
lock.lock();
try {
java.util.Optional<String> rdToAllocate = vpnUtil.allocateRdForExtraRouteAndUpdateUsedRdsMap(vpnId, null, prefix, vpnName, nextHop.getNextHopIpList().get(0), dpnId);
if (rdToAllocate.isPresent()) {
rd = rdToAllocate.get();
LOG.info("processVpnInterfaceAdjacencies: The rd {} is allocated for the extraroute {}", rd, prefix);
} else {
LOG.error("processVpnInterfaceAdjacencies: No rds to allocate extraroute {}", prefix);
continue;
}
} finally {
lock.unlock();
}
LOG.info("processVpnInterfaceAdjacencies: Added prefix {} and nextHopList {} as extra-route for vpn{}" + " interface {} on dpn {}", nextHop.getIpAddress(), nextHop.getNextHopIpList(), vpnName, interfaceName, dpnId);
}
// Please note that primary adjacency will use a subnet-gateway-mac-address that
// can be different from the gateway-mac-address within the VRFEntry as the
// gateway-mac-address is a superset.
RouteOrigin origin = VpnUtil.getRouteOrigin(nextHop.getAdjacencyType());
L3vpnInput input = new L3vpnInput().setNextHop(nextHop).setRd(rd).setVpnName(vpnName).setInterfaceName(interfaceName).setNextHopIp(nextHopIp).setPrimaryRd(primaryRd).setSubnetGatewayMacAddress(vpnInterfaceSubnetGwMacAddress).setRouteOrigin(origin);
Adjacency operationalAdjacency = null;
try {
operationalAdjacency = registeredPopulator.createOperationalAdjacency(input);
} catch (NullPointerException e) {
LOG.error("processVpnInterfaceAdjacencies: failed to create operational adjacency: input: {}, {}", input, e.getMessage());
return;
}
if (nextHop.getAdjacencyType() != AdjacencyType.PrimaryAdjacency) {
vpnManager.addExtraRoute(vpnName, nextHop.getIpAddress(), nextHop.getNextHopIpList().get(0), rd, vpnName, l3vni, origin, interfaceName, operationalAdjacency, encapType, prefixListForRefreshFib, writeConfigTxn);
}
value.add(operationalAdjacency);
}
AdjacenciesOp aug = VpnUtil.getVpnInterfaceOpDataEntryAugmentation(value);
addVpnInterfaceToOperational(vpnName, interfaceName, dpnId, aug, lportTag, gwMac.isPresent() ? gwMac.get() : null, gatewayIp, writeOperTxn);
L3vpnInput input = new L3vpnInput().setNextHopIp(nextHopIp).setL3vni(l3vni.longValue()).setPrimaryRd(primaryRd).setGatewayMac(gwMac.orElse(null)).setInterfaceName(interfaceName).setVpnName(vpnName).setDpnId(dpnId).setEncapType(encapType);
for (Adjacency nextHop : aug.nonnullAdjacency().values()) {
// Adjacencies other than primary Adjacencies are handled in the addExtraRoute call above.
if (nextHop.getAdjacencyType() == AdjacencyType.PrimaryAdjacency) {
RouteOrigin origin = VpnUtil.getRouteOrigin(nextHop.getAdjacencyType());
input.setNextHop(nextHop).setRd(nextHop.getVrfId()).setRouteOrigin(origin);
registeredPopulator.populateFib(input, writeConfigTxn);
}
}
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.adjacency.list.AdjacencyKey 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.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.adjacency.list.AdjacencyKey in project netvirt by opendaylight.
the class InterfaceStateChangeListener method handleMipAdjRemoval.
private void handleMipAdjRemoval(VpnInterface cfgVpnInterface, String vpnName) {
String interfaceName = cfgVpnInterface.getName();
Adjacencies adjacencies = cfgVpnInterface.augmentation(Adjacencies.class);
if (adjacencies != null) {
Map<AdjacencyKey, Adjacency> adjacencyMap = adjacencies.nonnullAdjacency();
if (!adjacencyMap.isEmpty()) {
for (Adjacency adj : adjacencyMap.values()) {
if (adj.getAdjacencyType() != Adjacency.AdjacencyType.PrimaryAdjacency) {
String ipAddress = adj.getIpAddress();
String prefix = ipAddress.split("/")[0];
LearntVpnVipToPort vpnVipToPort = vpnUtil.getLearntVpnVipToPort(vpnName, prefix);
if (vpnVipToPort != null && vpnVipToPort.getPortName().equals(interfaceName)) {
vpnUtil.removeMipAdjacency(vpnName, interfaceName, ipAddress, null);
} else {
LOG.debug("IP {} could be extra-route or learnt-ip on different interface" + "than oper-vpn-interface {}", ipAddress, interfaceName);
}
}
}
}
}
}
Aggregations