NAT failure due to Napt Switch-Over not happened 55/71655/14
authorxcheara <chetan.arakere@altencalsoftlabs.com>
Mon, 23 Apr 2018 05:41:26 +0000 (11:11 +0530)
committerSam Hague <shague@redhat.com>
Mon, 6 Aug 2018 16:27:04 +0000 (16:27 +0000)
Description :
Whenever a last VM part given VRF is deleted/migrated, it is required
to delete 'dpn-vpninterfaces-list' entry for given dpn-id from
'odl-l3vpn:neutron-router-dpns' Operational DS. This trigger
re-election of new Napt Switch which has VRF presence. But, when 2
VMs part of same VRF on a same DPN deleted simultaneously, then
there are chances that both of these event doesn't delete
'dpn-vpninterfaces-list' entry for the DPN which results in
non-triggering on new Napt Switch election. As a
result, the SNAT reverse traffic initiated from Non-Napt Switch
fail as FIB routes will not be available to carry back traffic
to non-napt switch.

Solution: Changes are done to make sure the 'dpn-vpninterfaces-list'
entry for DPN is deleted properly when last VM on that DPN is deleted
for a given VRF.

Issue : NETVIRT-1221

Change-Id: Idaebd8576762d12639d7bfbc26a89af94de4e991
Signed-off-by: xcheara <chetan.arakere@altencalsoftlabs.com>
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/ha/WeightedCentralizedSwitchScheduler.java
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/ExternalNetworksChangeListener.java
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/NatInterfaceStateChangeListener.java
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/NatRouterInterfaceListener.java
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/NatUtil.java

index 83cdf371d58710feb0689b6d20cab11205798c61..5fdf97769077e5130e9f3e332b7b918278e53ef4 100644 (file)
@@ -184,7 +184,8 @@ public class WeightedCentralizedSwitchScheduler implements CentralizedSwitchSche
                     vpnFootprintService.updateVpnToDpnMapping(primarySwitchId, routerName, primaryRd,
                             routerPort, null, false);
                     NatUtil.removeFromNeutronRouterDpnsMap(routerName, primarySwitchId, tx);
-                    NatUtil.removeFromDpnRoutersMap(dataBroker, routerName, routerName, interfaceManager, tx);
+                    NatUtil.removeFromDpnRoutersMap(dataBroker, routerName, routerName,
+                            primarySwitchId, interfaceManager, tx);
                     if (subnetIdToElanInstanceMap.containsKey(subnetUuid.getValue())) {
                         String elanInstanceName = subnetIdToElanInstanceMap.remove(subnetUuid.getValue());
                         NatUtil.removePseudoPortFromElanDpn(elanInstanceName, elanInstanceName, primarySwitchId,
index d6421e2e3a697aac5e0cbd275b5b56e7337ecaf3..c8ccbc536768e494d1e0209306eaa36dc1800991 100644 (file)
@@ -14,17 +14,14 @@ import java.math.BigInteger;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
-import java.util.concurrent.ExecutionException;
 import javax.annotation.PostConstruct;
 import javax.inject.Inject;
 import javax.inject.Singleton;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
-import org.opendaylight.genius.infra.Datastore.Configuration;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
-import org.opendaylight.genius.infra.TypedReadWriteTransaction;
 import org.opendaylight.genius.mdsalutil.MDSALUtil;
 import org.opendaylight.genius.mdsalutil.NwConstants;
 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
@@ -124,22 +121,18 @@ public class ExternalNetworksChangeListener
         //Check for VPN disassociation
         Uuid originalVpn = original.getVpnid();
         Uuid updatedVpn = update.getVpnid();
-        coordinator.enqueueJob(NatConstants.NAT_DJC_PREFIX + update.key(),
-            () -> Collections.singletonList(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
-                if (originalVpn == null && updatedVpn != null) {
-                    //external network is dis-associated from L3VPN instance
-                    associateExternalNetworkWithVPN(update, tx);
-                } else if (originalVpn != null && updatedVpn == null) {
-                    //external network is associated with vpn
-                    disassociateExternalNetworkFromVPN(update, originalVpn.getValue());
-                    //Remove the SNAT entries
-                    removeSnatEntries(original, original.getId(), tx);
-                }
-            })), NatConstants.NAT_DJC_MAX_RETRIES);
+        if (originalVpn == null && updatedVpn != null) {
+            //external network is dis-associated from L3VPN instance
+            associateExternalNetworkWithVPN(update);
+        } else if (originalVpn != null && updatedVpn == null) {
+            //external network is associated with vpn
+            disassociateExternalNetworkFromVPN(update, originalVpn.getValue());
+            //Remove the SNAT entries
+            removeSnatEntries(original, original.getId());
+        }
     }
 
-    private void removeSnatEntries(Networks original, Uuid networkUuid,
-        TypedReadWriteTransaction<Configuration> writeFlowInvTx) {
+    private void removeSnatEntries(Networks original, Uuid networkUuid) {
         List<Uuid> routerUuids = original.getRouterIds();
         for (Uuid routerUuid : routerUuids) {
             Long routerId = NatUtil.getVpnId(dataBroker, routerUuid.getValue());
@@ -149,14 +142,17 @@ public class ExternalNetworksChangeListener
             }
             Collection<String> externalIps = NatUtil.getExternalIpsForRouter(dataBroker,routerId);
             if (natMode == NatMode.Controller) {
-                externalRouterListener.handleDisableSnatInternetVpn(routerUuid.getValue(), routerId, networkUuid,
-                        externalIps, original.getVpnid().getValue(), writeFlowInvTx);
+                coordinator.enqueueJob(NatConstants.NAT_DJC_PREFIX + routerUuid.getValue(),
+                    () -> Collections.singletonList(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION,
+                        tx -> {
+                            externalRouterListener.handleDisableSnatInternetVpn(routerUuid.getValue(), routerId,
+                                networkUuid, externalIps, original.getVpnid().getValue(), tx);
+                        })), NatConstants.NAT_DJC_MAX_RETRIES);
             }
         }
     }
 
-    private void associateExternalNetworkWithVPN(Networks network, TypedReadWriteTransaction<Configuration> confTx)
-            throws ExecutionException, InterruptedException {
+    private void associateExternalNetworkWithVPN(Networks network) {
         List<Uuid> routerIds = network.getRouterIds();
         for (Uuid routerId : routerIds) {
             //long router = NatUtil.getVpnId(dataBroker, routerId.getValue());
@@ -181,9 +177,13 @@ public class ExternalNetworksChangeListener
                 }
                 List<InternalToExternalPortMap> intExtPortMapList = port.getInternalToExternalPortMap();
                 for (InternalToExternalPortMap ipMap : intExtPortMapList) {
-                    //remove all VPN related entries
-                    floatingIpListener.createNATFlowEntries(dpnId, portName, routerId.getValue(), network.getId(),
-                            ipMap, confTx);
+                    // remove all VPN related entries
+                    coordinator.enqueueJob(NatConstants.NAT_DJC_PREFIX + ipMap.key(),
+                        () -> Collections.singletonList(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION,
+                            tx -> {
+                                floatingIpListener.createNATFlowEntries(dpnId, portName, routerId.getValue(),
+                                    network.getId(), ipMap, tx);
+                            })), NatConstants.NAT_DJC_MAX_RETRIES);
                 }
             }
         }
@@ -217,49 +217,54 @@ public class ExternalNetworksChangeListener
                     routerId, dpnId);
                 return;
             }
+            final BigInteger finalDpnId = dpnId;
+            coordinator.enqueueJob(NatConstants.NAT_DJC_PREFIX + routerId.getValue(),
+                () -> Collections.singletonList(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION,
+                    confTx -> {
+                        Long routerIdentifier = NatUtil.getVpnId(dataBroker, routerId.getValue());
+                        InstanceIdentifierBuilder<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
+                            .rev160111.intext.ip.map.IpMapping> idBuilder =
+                            InstanceIdentifier.builder(IntextIpMap.class)
+                                .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111
+                                    .intext.ip.map.IpMapping.class,
+                                    new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111
+                                        .intext.ip.map.IpMappingKey(routerIdentifier));
+                        InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111
+                            .intext.ip.map.IpMapping> id = idBuilder.build();
+                        Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111
+                            .intext.ip.map.IpMapping> ipMapping = MDSALUtil.read(dataBroker,
+                                    LogicalDatastoreType.OPERATIONAL, id);
+                        if (ipMapping.isPresent()) {
+                            List<IpMap> ipMaps = ipMapping.get().getIpMap();
+                            for (IpMap ipMap : ipMaps) {
+                                String externalIp = ipMap.getExternalIp();
+                                LOG.debug("associateExternalNetworkWithVPN : Calling advToBgpAndInstallFibAndTsFlows "
+                                    + "for dpnId {},vpnName {} and externalIp {}", finalDpnId, vpnName, externalIp);
+                                if (natMode == NatMode.Controller) {
+                                    externalRouterListener.advToBgpAndInstallFibAndTsFlows(finalDpnId,
+                                            NwConstants.INBOUND_NAPT_TABLE, vpnName, routerIdentifier,
+                                            routerId.getValue(), externalIp, network.getId(),
+                                            null /* external-router */, confTx);
+                                }
+                            }
+                        } else {
+                            LOG.warn("associateExternalNetworkWithVPN: No ipMapping present fot the routerId {}",
+                                    routerId);
+                        }
 
-            Long routerIdentifier = NatUtil.getVpnId(dataBroker, routerId.getValue());
-            InstanceIdentifierBuilder<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
-                .rev160111.intext.ip.map.IpMapping> idBuilder =
-                InstanceIdentifier.builder(IntextIpMap.class)
-                    .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111
-                        .intext.ip.map.IpMapping.class,
-                        new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111
-                            .intext.ip.map.IpMappingKey(routerIdentifier));
-            InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111
-                .intext.ip.map.IpMapping> id = idBuilder.build();
-            Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111
-                .intext.ip.map.IpMapping> ipMapping = MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
-            if (ipMapping.isPresent()) {
-                List<IpMap> ipMaps = ipMapping.get().getIpMap();
-                for (IpMap ipMap : ipMaps) {
-                    String externalIp = ipMap.getExternalIp();
-                    LOG.debug("associateExternalNetworkWithVPN : Calling advToBgpAndInstallFibAndTsFlows for dpnId {},"
-                        + "vpnName {} and externalIp {}", dpnId, vpnName, externalIp);
-                    if (natMode == NatMode.Controller) {
-                        externalRouterListener.advToBgpAndInstallFibAndTsFlows(dpnId, NwConstants.INBOUND_NAPT_TABLE,
-                                vpnName, routerIdentifier, routerId.getValue(),
-                                externalIp, network.getId(), null /* external-router */,
-                                confTx);
-                    }
-                }
-            } else {
-                LOG.warn("associateExternalNetworkWithVPN : No ipMapping present fot the routerId {}", routerId);
-            }
-
-            long vpnId = NatUtil.getVpnId(dataBroker, vpnName);
-            // Install 47 entry to point to 21
-            if (natMode == NatMode.Controller) {
-                externalRouterListener.installNaptPfibEntriesForExternalSubnets(routerId.getValue(), dpnId,
-                        confTx);
-                if (vpnId != -1) {
-                    LOG.debug("associateExternalNetworkWithVPN : Calling externalRouterListener installNaptPfibEntry "
-                            + "for dpnId {} and vpnId {}", dpnId, vpnId);
-                    externalRouterListener.installNaptPfibEntry(dpnId, vpnId, confTx);
-                }
-            }
+                        long vpnId = NatUtil.getVpnId(dataBroker, vpnName);
+                        // Install 47 entry to point to 21
+                        if (natMode == NatMode.Controller) {
+                            externalRouterListener.installNaptPfibEntriesForExternalSubnets(routerId.getValue(),
+                                    finalDpnId, confTx);
+                            if (vpnId != -1) {
+                                LOG.debug("associateExternalNetworkWithVPN : Calling externalRouterListener "
+                                        + "installNaptPfibEntry for dpnId {} and vpnId {}", finalDpnId, vpnId);
+                                externalRouterListener.installNaptPfibEntry(finalDpnId, vpnId, confTx);
+                            }
+                        }
+                    })), NatConstants.NAT_DJC_MAX_RETRIES);
         }
-
     }
 
     private void disassociateExternalNetworkFromVPN(Networks network, String vpnName) {
@@ -276,25 +281,23 @@ public class ExternalNetworksChangeListener
             }
             RouterPorts routerPorts = optRouterPorts.get();
             List<Ports> interfaces = routerPorts.getPorts();
-            try {
-                txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
-                    for (Ports port : interfaces) {
-                        String portName = port.getPortName();
-                        BigInteger dpnId = NatUtil.getDpnForInterface(interfaceManager, portName);
-                        if (dpnId.equals(BigInteger.ZERO)) {
-                            LOG.debug("disassociateExternalNetworkFromVPN : DPN not found for {},"
-                                    + "skip handling of ext nw {} disassociation", portName, network.getId());
-                            continue;
-                        }
-                        List<InternalToExternalPortMap> intExtPortMapList = port.getInternalToExternalPortMap();
-                        for (InternalToExternalPortMap intExtPortMap : intExtPortMapList) {
-                            floatingIpListener.removeNATFlowEntries(dpnId, portName, vpnName, routerId.getValue(),
+            for (Ports port : interfaces) {
+                String portName = port.getPortName();
+                BigInteger dpnId = NatUtil.getDpnForInterface(interfaceManager, portName);
+                if (dpnId.equals(BigInteger.ZERO)) {
+                    LOG.debug("disassociateExternalNetworkFromVPN : DPN not found for {},"
+                            + "skip handling of ext nw {} disassociation", portName, network.getId());
+                    continue;
+                }
+                List<InternalToExternalPortMap> intExtPortMapList = port.getInternalToExternalPortMap();
+                for (InternalToExternalPortMap intExtPortMap : intExtPortMapList) {
+                    coordinator.enqueueJob(NatConstants.NAT_DJC_PREFIX + intExtPortMap.key(),
+                        () -> Collections.singletonList(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION,
+                            tx -> {
+                                floatingIpListener.removeNATFlowEntries(dpnId, portName, vpnName, routerId.getValue(),
                                     intExtPortMap, tx);
-                        }
-                    }
-                }).get();
-            } catch (ExecutionException | InterruptedException e) {
-                LOG.error("Error writing to datastore {}", e);
+                            })), NatConstants.NAT_DJC_MAX_RETRIES);
+                }
             }
         }
     }
index bfce16cb21d5ebd5ac64eedc4e04025f816910b2..bb985ac39377cfc323427622fdd6ed94b3a20c6b 100644 (file)
@@ -324,8 +324,11 @@ public class NatInterfaceStateChangeListener
             List<ListenableFuture<Void>> futures = new ArrayList<>();
             try {
                 LOG.trace("call : Received interface {} PORT UP OR ADD event ", interfaceName);
-                futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, tx ->
-                    handleRouterInterfacesUpEvent(routerName, interfaceName, intfDpnId, tx)));
+                String dpnLock = NatConstants.NAT_DJC_PREFIX + intfDpnId;
+                synchronized (dpnLock.intern()) {
+                    futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, tx ->
+                        handleRouterInterfacesUpEvent(routerName, interfaceName, intfDpnId, tx)));
+                }
             } catch (Exception e) {
                 LOG.error("call : Exception caught in Interface {} Operational State Up event",
                         interfaceName, e);
@@ -351,8 +354,11 @@ public class NatInterfaceStateChangeListener
             List<ListenableFuture<Void>> futures = new ArrayList<>();
             try {
                 LOG.trace("call : Received interface {} PORT DOWN or REMOVE event", interfaceName);
-                futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, tx ->
+                String dpnLock = NatConstants.NAT_DJC_PREFIX + intfDpnId;
+                synchronized (dpnLock.intern()) {
+                    futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, tx ->
                         handleRouterInterfacesDownEvent(routerName, interfaceName, intfDpnId, tx)));
+                }
             } catch (Exception e) {
                 LOG.error("call : Exception observed in handling deletion of VPN Interface {}.", interfaceName, e);
             }
@@ -381,27 +387,31 @@ public class NatInterfaceStateChangeListener
                 final String interfaceName = update.getName();
                 LOG.trace("call : Received interface {} state change event", interfaceName);
                 LOG.debug("call : DPN ID {} for the interface {} ", intfDpnId, interfaceName);
-                IntfTransitionState state = getTransitionState(original.getOperStatus(), update.getOperStatus());
-                if (state.equals(IntfTransitionState.STATE_IGNORE)) {
-                    LOG.info("NAT Service: Interface {} state original {} updated {} not handled",
-                            interfaceName, original.getOperStatus(), update.getOperStatus());
-                    return futures;
-                }
-                futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, tx -> {
-                    if (state.equals(IntfTransitionState.STATE_DOWN)) {
-                        LOG.debug("call : DPN {} connnected to the interface {} has gone down."
-                                + "Hence clearing the dpn-vpninterfaces-list entry from the"
-                                + " neutron-router-dpns model in the ODL:L3VPN", intfDpnId, interfaceName);
-                        // If the interface state is unknown, it means that the corresponding DPN has gone down.
-                        // So remove the dpn-vpninterfaces-list from the neutron-router-dpns model.
-                        NatUtil.removeFromNeutronRouterDpnsMap(routerName, intfDpnId, tx);
-                    } else if (state.equals(IntfTransitionState.STATE_UP)) {
-                        LOG.debug("call : DPN {} connnected to the interface {} has come up. Hence adding"
-                                + " the dpn-vpninterfaces-list entry from the neutron-router-dpns model"
-                                + " in the ODL:L3VPN", intfDpnId, interfaceName);
-                        handleRouterInterfacesUpEvent(routerName, interfaceName, intfDpnId, tx);
+                String dpnLock = NatConstants.NAT_DJC_PREFIX + intfDpnId;
+                synchronized (dpnLock.intern()) {
+                    IntfTransitionState state = getTransitionState(original.getOperStatus(), update.getOperStatus());
+                    if (state.equals(IntfTransitionState.STATE_IGNORE)) {
+                        LOG.info("NAT Service: Interface {} state original {} updated {} not handled",
+                                interfaceName, original.getOperStatus(), update.getOperStatus());
+                        return futures;
                     }
-                }));
+                    futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, tx -> {
+                        if (state.equals(IntfTransitionState.STATE_DOWN)) {
+                            LOG.debug("call : DPN {} connnected to the interface {} has gone down."
+                                    + "Hence clearing the dpn-vpninterfaces-list entry from the"
+                                    + " neutron-router-dpns model in the ODL:L3VPN", intfDpnId, interfaceName);
+                            // If the interface state is unknown, it means that the corresponding DPN has gone down.
+                            // So remove the dpn-vpninterfaces-list from the neutron-router-dpns model.
+                            NatUtil.removeFromNeutronRouterDpnsMap(routerName, interfaceName,
+                                    intfDpnId, tx);
+                        } else if (state.equals(IntfTransitionState.STATE_UP)) {
+                            LOG.debug("call : DPN {} connnected to the interface {} has come up. Hence adding"
+                                    + " the dpn-vpninterfaces-list entry from the neutron-router-dpns model"
+                                    + " in the ODL:L3VPN", intfDpnId, interfaceName);
+                            handleRouterInterfacesUpEvent(routerName, interfaceName, intfDpnId, tx);
+                        }
+                    }));
+                }
             } catch (Exception e) {
                 LOG.error("call : Exception observed in handling updation of VPN Interface {}.", update.getName(), e);
             }
index cfe80912011123d43609bdd1b57088d6d4227eb2..a1e30a259a7fd6fc2d57a5fe99b7063067f027a3 100644 (file)
@@ -91,10 +91,14 @@ public class NatRouterInterfaceListener
                         interfaceName, routerId);
                 return;
             }
-            ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, operTx -> {
-                NatUtil.addToNeutronRouterDpnsMap(routerId, interfaceName, dpId, operTx);
-                NatUtil.addToDpnRoutersMap(routerId, interfaceName, dpId, operTx);
-            }), LOG, "Error processing NAT router interface addition");
+            String dpnLock = NatConstants.NAT_DJC_PREFIX + dpId;
+            synchronized (dpnLock.intern()) {
+                ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL,
+                    operTx -> {
+                        NatUtil.addToNeutronRouterDpnsMap(routerId, interfaceName, dpId, operTx);
+                        NatUtil.addToDpnRoutersMap(routerId, interfaceName, dpId, operTx);
+                    }), LOG, "Error processing NAT router interface addition");
+            }
         } else {
             LOG.info("add : Interface {} not yet operational to handle router interface add event in router {}",
                     interfaceName, routerId);
@@ -112,13 +116,21 @@ public class NatRouterInterfaceListener
             confTx -> confTx.delete(NatUtil.getRouterInterfaceId(interfaceName))), LOG,
             "Error handling NAT router interface removal");
 
-        ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, operTx -> {
-            //Delete the NeutronRouterDpnMap from the ODL:L3VPN operational model
-            NatUtil.removeFromNeutronRouterDpnsMap(routerId, interfaceName, interfaceManager, operTx);
-
-            //Delete the DpnRouterMap from the ODL:L3VPN operational model
-            NatUtil.removeFromDpnRoutersMap(dataBroker, routerId, interfaceName, interfaceManager, operTx);
-        }), LOG, "Error handling NAT router interface removal");
+        BigInteger dpId = NatUtil.getDpnForInterface(interfaceManager, interfaceName);
+        if (dpId.equals(BigInteger.ZERO)) {
+            LOG.warn("REMOVE : Could not retrieve DPN ID for interface {} to handle router {} dissociation model",
+                    interfaceName, routerId);
+            return;
+        }
+        String dpnLock = NatConstants.NAT_DJC_PREFIX + dpId;
+        synchronized (dpnLock.intern()) {
+            ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, operTx -> {
+                //Delete the NeutronRouterDpnMap from the ODL:L3VPN operational model
+                NatUtil.removeFromNeutronRouterDpnsMap(routerId, interfaceName, dpId, operTx);
+                //Delete the DpnRouterMap from the ODL:L3VPN operational model
+                NatUtil.removeFromDpnRoutersMap(dataBroker, routerId, interfaceName, dpId, interfaceManager, operTx);
+            }), LOG, "Error handling NAT router interface removal");
+        }
     }
 
     @Override
index a7d56e6596ffed61bae20139602d7d9770c54fba..9b7dfcfcd009afab098f33af16b62f157bb13830 100644 (file)
@@ -1175,13 +1175,7 @@ public final class NatUtil {
     }
 
     public static void removeFromNeutronRouterDpnsMap(String routerName, String vpnInterfaceName,
-        OdlInterfaceRpcService ifaceMgrRpcService, @Nonnull TypedReadWriteTransaction<Operational> operTx) {
-        BigInteger dpId = getDpnForInterface(ifaceMgrRpcService, vpnInterfaceName);
-        if (dpId.equals(BigInteger.ZERO)) {
-            LOG.debug("removeFromNeutronRouterDpnsMap : Could not retrieve dp id for interface {} to handle router {}"
-                    + " dissociation model", vpnInterfaceName, routerName);
-            return;
-        }
+         BigInteger dpId, @Nonnull TypedReadWriteTransaction<Operational> operTx) {
         InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
         Optional<DpnVpninterfacesList> optionalRouterDpnList;
         try {
@@ -1192,40 +1186,27 @@ public final class NatUtil {
         }
         if (optionalRouterDpnList.isPresent()) {
             List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns
-                .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces =
-                optionalRouterDpnList.get().getRouterInterfaces();
+                    .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces =
+                    optionalRouterDpnList.get().getRouterInterfaces();
             org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn
-                .list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
-                new RouterInterfacesBuilder().withKey(new RouterInterfacesKey(vpnInterfaceName))
-                    .setInterface(vpnInterfaceName).build();
+                    .list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
+                    new RouterInterfacesBuilder().withKey(new RouterInterfacesKey(vpnInterfaceName))
+                            .setInterface(vpnInterfaceName).build();
 
             if (routerInterfaces != null && routerInterfaces.remove(routerInterface)) {
                 if (routerInterfaces.isEmpty()) {
                     operTx.delete(routerDpnListIdentifier);
                 } else {
                     operTx.delete(routerDpnListIdentifier.child(
-                        org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
-                            .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
-                        new RouterInterfacesKey(vpnInterfaceName)));
+                            org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
+                                    .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
+                            new RouterInterfacesKey(vpnInterfaceName)));
                 }
             }
         }
     }
 
     public static void removeFromDpnRoutersMap(DataBroker broker, String routerName, String vpnInterfaceName,
-        OdlInterfaceRpcService ifaceMgrRpcService, TypedReadWriteTransaction<Operational> operTx)
-        throws ExecutionException, InterruptedException {
-        BigInteger dpId = getDpnForInterface(ifaceMgrRpcService, vpnInterfaceName);
-        if (dpId.equals(BigInteger.ZERO)) {
-            LOG.debug("removeFromDpnRoutersMap : removeFromDpnRoutersMap() : "
-                + "Could not retrieve DPN ID for interface {} to handle router {} dissociation model",
-                vpnInterfaceName, routerName);
-            return;
-        }
-        removeFromDpnRoutersMap(broker, routerName, vpnInterfaceName, dpId, ifaceMgrRpcService, operTx);
-    }
-
-    static void removeFromDpnRoutersMap(DataBroker broker, String routerName, String vpnInterfaceName,
         BigInteger curDpnId, OdlInterfaceRpcService ifaceMgrRpcService, TypedReadWriteTransaction<Operational> operTx)
         throws ExecutionException, InterruptedException {
         /*