Unsupported operation exception handling
[netvirt.git] / neutronvpn / impl / src / main / java / org / opendaylight / netvirt / neutronvpn / NeutronvpnNatManager.java
index d934b777da00da68ac3a6daea4456cda44fbfb37..92c801cce9d031610c68c6808c3befa3acd44299 100644 (file)
@@ -9,21 +9,34 @@ package org.opendaylight.netvirt.neutronvpn;
 
 import com.google.common.base.Optional;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Objects;
 import java.util.Set;
 import javax.annotation.PreDestroy;
 import javax.inject.Inject;
 import javax.inject.Singleton;
+import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
-import org.opendaylight.netvirt.neutronvpn.api.enums.IpVersionChoice;
+import org.opendaylight.netvirt.elanmanager.api.IElanService;
 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.Adjacencies;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.NeutronRouterDpns;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.Adjacency;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPort;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalNetworks;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalSubnets;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpInfo;
@@ -42,7 +55,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev16011
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.SubnetsKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPorts;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPortsKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.router.ExternalGatewayInfo;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.router.external_gateway_info.ExternalFixedIps;
@@ -62,23 +74,23 @@ public class NeutronvpnNatManager implements AutoCloseable {
 
     private final DataBroker dataBroker;
     private final NeutronvpnUtils neutronvpnUtils;
-    private final NeutronvpnManager nvpnManager;
+    private final IElanService elanService;
 
     @Inject
     public NeutronvpnNatManager(final DataBroker dataBroker, final NeutronvpnUtils neutronvpnUtils,
-                                  final NeutronvpnManager neutronvpnManager) {
+                                final IElanService elanService) {
         this.dataBroker = dataBroker;
         this.neutronvpnUtils = neutronvpnUtils;
-        this.nvpnManager = neutronvpnManager;
+        this.elanService = elanService;
     }
 
     @Override
     @PreDestroy
-    public void close() throws Exception {
+    public void close() {
         LOG.info("{} close", getClass().getSimpleName());
     }
 
-    public void handleExternalNetworkForRouter(Router original, Router update) {
+    public void handleExternalNetworkForRouter(@Nullable Router original, Router update) {
         Uuid routerId = update.getUuid();
         Uuid origExtNetId = null;
         Uuid updExtNetId = null;
@@ -89,7 +101,7 @@ public class NeutronvpnNatManager implements AutoCloseable {
         if (extNetChanged != EXTERNAL_NO_CHANGE) {
             if (extNetChanged == EXTERNAL_ADDED) {
                 updExtNetId = update.getExternalGatewayInfo().getExternalNetworkId();
-                LOG.trace("External Network {} addition detected for router", updExtNetId.getValue(),
+                LOG.trace("External Network {} addition detected for router {}", updExtNetId.getValue(),
                         routerId.getValue());
                 addExternalNetworkToRouter(update);
                 return;
@@ -124,7 +136,7 @@ public class NeutronvpnNatManager implements AutoCloseable {
         }
     }
 
-    private int externalNetworkChanged(Router original, Router update) {
+    private static int externalNetworkChanged(Router original, Router update) {
         String origExtNet = null;
         String newExtNet = null;
         if (original != null && original.getExternalGatewayInfo() != null) {
@@ -151,7 +163,7 @@ public class NeutronvpnNatManager implements AutoCloseable {
         }
     }
 
-    private boolean snatSettingChanged(Router orig, Router update) {
+    private static boolean snatSettingChanged(Router orig, Router update) {
         ExternalGatewayInfo origExtGw = null;
         ExternalGatewayInfo newExtGw = null;
         if (orig != null && orig.getExternalGatewayInfo() != null) {
@@ -172,7 +184,7 @@ public class NeutronvpnNatManager implements AutoCloseable {
         return false;
     }
 
-    private boolean externalFixedIpsChanged(Router orig, Router update) {
+    private static boolean externalFixedIpsChanged(Router orig, Router update) {
         ExternalGatewayInfo origExtGw = null;
         ExternalGatewayInfo newExtGw = null;
         if (orig != null && orig.getExternalGatewayInfo() != null) {
@@ -197,15 +209,15 @@ public class NeutronvpnNatManager implements AutoCloseable {
             if (origExtGw.getExternalFixedIps() != null) {
                 if (!origExtGw.getExternalFixedIps().isEmpty()) {
                     if (newExtGw.getExternalFixedIps() != null && !newExtGw.getExternalFixedIps().isEmpty()) {
-                        List<ExternalFixedIps> origExtFixedIps = origExtGw.getExternalFixedIps();
+                        List<ExternalFixedIps> origExtFixedIps = new ArrayList<>(origExtGw.nonnullExternalFixedIps());
                         HashSet<String> origFixedIpSet = new HashSet<>();
                         for (ExternalFixedIps fixedIps : origExtFixedIps) {
-                            origFixedIpSet.add(fixedIps.getIpAddress().getIpv4Address().getValue());
+                            origFixedIpSet.add(fixedIps.getIpAddress().stringValue());
                         }
-                        List<ExternalFixedIps> newExtFixedIps = newExtGw.getExternalFixedIps();
+                        List<ExternalFixedIps> newExtFixedIps = new ArrayList<>(newExtGw.nonnullExternalFixedIps());
                         HashSet<String> updFixedIpSet = new HashSet<>();
                         for (ExternalFixedIps fixedIps : newExtFixedIps) {
-                            updFixedIpSet.add(fixedIps.getIpAddress().getIpv4Address().getValue());
+                            updFixedIpSet.add(fixedIps.getIpAddress().stringValue());
                         }
                         // returns true if external subnets have changed
                         return !origFixedIpSet.equals(updFixedIpSet) ? true : false;
@@ -243,7 +255,7 @@ public class NeutronvpnNatManager implements AutoCloseable {
                 return;
             }
             NetworksBuilder builder = null;
-            builder = new NetworksBuilder().setKey(new NetworksKey(extNetId)).setId(extNetId);
+            builder = new NetworksBuilder().withKey(new NetworksKey(extNetId)).setId(extNetId);
             builder.setVpnid(neutronvpnUtils.getVpnForNetwork(extNetId));
             builder.setRouterIds(new ArrayList<>());
             builder.setProviderNetworkType(provType);
@@ -315,10 +327,8 @@ public class NeutronvpnNatManager implements AutoCloseable {
                 return;
             }
             NetworksBuilder builder = new NetworksBuilder(optionalNets.get());
-            List<Uuid> rtrList = builder.getRouterIds();
-            if (rtrList == null) {
-                rtrList = new ArrayList<>();
-            }
+            List<Uuid> rtrList = (builder.getRouterIds() != null && !builder.getRouterIds().isEmpty())
+                    ? new ArrayList<>(builder.getRouterIds()) : new ArrayList<>();
             rtrList.add(routerId);
             builder.setRouterIds(rtrList);
             if (NeutronvpnUtils.isFlatOrVlanNetwork(input)) {
@@ -331,27 +341,6 @@ public class NeutronvpnNatManager implements AutoCloseable {
             SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, netsIdentifier,
                     networkss);
             LOG.trace("Updated externalnetworks successfully to CONFIG Datastore");
-            //get vpn external form this network external to setup vpnInternet for ipv6
-            Uuid vpnExternal = neutronvpnUtils.getVpnForNetwork(extNetId);
-            if (vpnExternal == null) {
-                LOG.debug("addExternalNetworkToRouter : no vpnExternal for Network {}", extNetId);
-            }
-            LOG.debug("addExternalNetworkToRouter : the vpnExternal {}", vpnExternal);
-            //get subnetmap associate to the router, any subnetmap "external" could be existing
-            List<Subnetmap> snList = neutronvpnUtils.getNeutronRouterSubnetMaps(routerId);
-            LOG.debug("addExternalNetworkToRouter : the vpnExternal {} subnetmap to be set with vpnInternet {}",
-                    vpnExternal, snList);
-            for (Subnetmap sn : snList) {
-                if (sn.getInternetVpnId() == null) {
-                    continue;
-                }
-                IpVersionChoice ipVers = neutronvpnUtils.getIpVersionFromString(sn.getSubnetIp());
-                if (ipVers == IpVersionChoice.IPV6) {
-                    LOG.debug("addExternalNetworkToRouter : setup vpnInternet IPv6 for vpnExternal {} subnetmap {}",
-                            vpnExternal, sn);
-                    nvpnManager.updateVpnInternetForSubnet(sn, vpnExternal, true);
-                }
-            }
         } catch (TransactionCommitFailedException | ReadFailedException ex) {
             LOG.error("Creation of externalnetworks failed for {}",
                 extNetId.getValue(), ex);
@@ -363,7 +352,7 @@ public class NeutronvpnNatManager implements AutoCloseable {
         Uuid routerId = update.getUuid();
 
         // Remove the router to the ExtRouters list
-        removeExternalRouter(origExtNetId, update);
+        removeExternalRouter(update);
 
         //Remove router entry from floating-ip-info list
         removeRouterFromFloatingIpInfo(update, dataBroker);
@@ -379,48 +368,32 @@ public class NeutronvpnNatManager implements AutoCloseable {
             optionalNets = SingleTransactionDataBroker.syncReadOptional(dataBroker,
                                             LogicalDatastoreType.CONFIGURATION, netsIdentifier);
         } catch (ReadFailedException ex) {
-            LOG.error("Removing externalnetwork {} from router {} failed", origExtNetId.getValue(),
-                    routerId.getValue(), ex);
+            LOG.error("removeExternalNetworkFromRouter: Failed to remove provider network {} from router {}",
+                      origExtNetId.getValue(), routerId.getValue(), ex);
             return;
         }
         if (!optionalNets.isPresent()) {
-            LOG.error("External Network {} not present in the NVPN datamodel", origExtNetId.getValue());
+            LOG.error("removeExternalNetworkFromRouter: Provider Network {} not present in the NVPN datamodel",
+                      origExtNetId.getValue());
             return;
         }
         Networks nets = optionalNets.get();
         try {
-            LOG.trace("Removing a router from External Networks node: {}", origExtNetId.getValue());
             NetworksBuilder builder = new NetworksBuilder(nets);
-            List<Uuid> rtrList = builder.getRouterIds();
+            List<Uuid> rtrList = new ArrayList<>();
+            rtrList = builder.getRouterIds() != null ? new ArrayList<>(builder.getRouterIds()) : rtrList;
             if (rtrList != null) {
                 rtrList.remove(routerId);
                 builder.setRouterIds(rtrList);
                 Networks networkss = builder.build();
                 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
                         netsIdentifier, networkss);
-                LOG.trace("Removed router {} from externalnetworks {}", routerId, origExtNetId.getValue());
+                LOG.trace("removeExternalNetworkFromRouter: Remove router {} from External Networks node {}",
+                          routerId, origExtNetId.getValue());
             }
         } catch (TransactionCommitFailedException ex) {
-            LOG.error("Removing externalnetwork {} from router {} failed", origExtNetId.getValue(),
-                    routerId.getValue(), ex);
-        }
-
-        // Remove the vpnInternetId fromSubnetmap
-        LOG.trace("Removing a vpnInternetId to SubnetMaps about External Networks node: {}",
-                origExtNetId.getValue());
-        Network net = neutronvpnUtils.getNeutronNetwork(nets.getId());
-        List<Subnetmap> submapList = neutronvpnUtils.getSubnetMapsforNetworkRoute(net);
-        for (Subnetmap sn : submapList) {
-            if (sn.getInternetVpnId() == null) {
-                continue;
-            }
-            LOG.trace("Removing a vpnInternetId {} to SubnetMap {}", sn.getInternetVpnId(), sn.getId());
-            IpVersionChoice ipVers = NeutronvpnUtils.getIpVersionFromString(sn.getSubnetIp());
-            if (ipVers == IpVersionChoice.IPV6) {
-                LOG.debug("removeExternalNetworkFromRouter : clear vpnInternet IPv6 for vpnExternal {} "
-                        + "subnetmap {}", sn.getInternetVpnId(), sn);
-                nvpnManager.updateVpnInternetForSubnet(sn, sn.getInternetVpnId(), false);
-            }
+            LOG.error("removeExternalNetworkFromRouter: Failed to remove provider network {} from router {}",
+                      origExtNetId.getValue(), routerId.getValue(), ex);
         }
     }
 
@@ -448,14 +421,14 @@ public class NeutronvpnNatManager implements AutoCloseable {
             if (optionalRouters.isPresent()) {
                 builder = new RoutersBuilder(optionalRouters.get());
             } else {
-                builder = new RoutersBuilder().setKey(new RoutersKey(routerId.getValue()));
+                builder = new RoutersBuilder().withKey(new RoutersKey(routerId.getValue()));
             }
             builder.setRouterName(routerId.getValue());
             builder.setNetworkId(extNetId);
             builder.setEnableSnat(update.getExternalGatewayInfo().isEnableSnat());
 
             ArrayList<ExternalIps> externalIps = new ArrayList<>();
-            for (ExternalFixedIps fixedIps : update.getExternalGatewayInfo().getExternalFixedIps()) {
+            for (ExternalFixedIps fixedIps : update.getExternalGatewayInfo().nonnullExternalFixedIps()) {
                 addExternalFixedIpToExternalIpsList(externalIps, fixedIps);
             }
             builder.setExternalIps(externalIps);
@@ -484,7 +457,7 @@ public class NeutronvpnNatManager implements AutoCloseable {
 
     // TODO Clean up the exception handling
     @SuppressWarnings("checkstyle:IllegalCatch")
-    private void removeExternalRouter(Uuid extNetId, Router update) {
+    private void removeExternalRouter(Router update) {
         Uuid routerId = update.getUuid();
 
         InstanceIdentifier<Routers> routersIdentifier = NeutronvpnUtils.buildExtRoutersIdentifier(routerId);
@@ -507,6 +480,31 @@ public class NeutronvpnNatManager implements AutoCloseable {
         }
     }
 
+    public void removeNeutronRouterDpns(Router router) {
+        Uuid routerId = router.getUuid();
+        InstanceIdentifier<RouterDpnList> iid = InstanceIdentifier.builder(NeutronRouterDpns.class)
+                .child(RouterDpnList.class, new RouterDpnListKey(routerId.getValue())).build();
+        neutronvpnUtils.asyncReadAndExecute(LogicalDatastoreType.OPERATIONAL, iid, router.getUuid().toString(),
+            (routerDpnListOptional) -> {
+                if (routerDpnListOptional.isPresent()) {
+                    if (routerDpnListOptional.get().getDpnVpninterfacesList() != null) {
+                        routerDpnListOptional.get().getDpnVpninterfacesList().stream()
+                                .filter((dpnList) -> (dpnList != null))
+                                .forEach((dpnList) -> {
+                                    LOG.warn("DPN {} presence exists while deleting router instance {}",
+                                            dpnList.getDpnId(), routerId);
+                                });
+                        try {
+                            SingleTransactionDataBroker.syncDelete(dataBroker, LogicalDatastoreType.OPERATIONAL, iid);
+                        } catch (TransactionCommitFailedException e) {
+                            LOG.warn("Failed to read from NeutronRouterDpn DS for routerid {}", routerId, e);
+                        }
+                    }
+                }
+                return null;
+            });
+    }
+
     private void removeRouterFromFloatingIpInfo(Router update, DataBroker broker) {
         Uuid routerId = update.getUuid();
         InstanceIdentifier.InstanceIdentifierBuilder<RouterPorts> routerPortsIdentifierBuilder = InstanceIdentifier
@@ -615,7 +613,7 @@ public class NeutronvpnNatManager implements AutoCloseable {
         }
     }
 
-    public void updateOrAddExternalSubnet(Uuid networkId, Uuid subnetId, List<Uuid> routerIds) {
+    public void updateOrAddExternalSubnet(Uuid networkId, Uuid subnetId, @Nullable List<Uuid> routerIds) {
         Optional<Subnets> optionalExternalSubnets = neutronvpnUtils.getOptionalExternalSubnets(subnetId);
         if (optionalExternalSubnets.isPresent()) {
             LOG.trace("Will update external subnet {} with networkId {} and routerIds {}",
@@ -641,7 +639,7 @@ public class NeutronvpnNatManager implements AutoCloseable {
         }
     }
 
-    public void updateExternalSubnet(Uuid networkId, Uuid subnetId, List<Uuid> routerIds) {
+    public void updateExternalSubnet(Uuid networkId, Uuid subnetId, @Nullable List<Uuid> routerIds) {
         InstanceIdentifier<Subnets> subnetsIdentifier = InstanceIdentifier.builder(ExternalSubnets.class)
                 .child(Subnets.class, new SubnetsKey(subnetId)).build();
         try {
@@ -654,7 +652,8 @@ public class NeutronvpnNatManager implements AutoCloseable {
         }
     }
 
-    public void removeExternalSubnet(Uuid subnetId) {
+    public void removeExternalSubnet(Uuid networkId, Uuid subnetId) {
+        removeAdjacencyAndLearnedEntriesforExternalSubnet(networkId, subnetId);
         InstanceIdentifier<Subnets> subnetsIdentifier = InstanceIdentifier.builder(ExternalSubnets.class)
                 .child(Subnets.class, new SubnetsKey(subnetId)).build();
         try {
@@ -670,25 +669,24 @@ public class NeutronvpnNatManager implements AutoCloseable {
         if (optionalExternalSubnets.isPresent()) {
             Subnets subnets = optionalExternalSubnets.get();
             List<Uuid> routerIds;
-            if (subnets.getRouterIds() != null) {
-                routerIds = subnets.getRouterIds();
+            if (subnets.getRouterIds() != null && !subnets.getRouterIds().isEmpty()) {
+                routerIds = new ArrayList<>(subnets.getRouterIds());
             } else {
                 routerIds = new ArrayList<>();
             }
 
             if (subnets.getExternalNetworkId() != null
                     && subnets.getExternalNetworkId().equals(networkId) && !routerIds.contains(routerId)) {
-                LOG.debug("Will add routerID {} for external subnet.",
-                        routerId, subnetId);
+                LOG.debug("Will add routerID {} for external subnet {}.", routerId, subnetId);
                 routerIds.add(routerId);
                 updateExternalSubnet(networkId, subnetId, routerIds);
             }
         }
     }
 
-    private Subnets createSubnets(Uuid subnetId, Uuid networkId, List<Uuid> routerIds) {
+    private static Subnets createSubnets(Uuid subnetId, Uuid networkId, @Nullable List<Uuid> routerIds) {
         SubnetsBuilder subnetsBuilder = new SubnetsBuilder();
-        subnetsBuilder.setKey(new SubnetsKey(subnetId));
+        subnetsBuilder.withKey(new SubnetsKey(subnetId));
         subnetsBuilder.setId(subnetId);
         subnetsBuilder.setVpnId(subnetId);
         subnetsBuilder.setExternalNetworkId(networkId);
@@ -717,21 +715,22 @@ public class NeutronvpnNatManager implements AutoCloseable {
         List<Subnets> fixedIpsSubnets = getSubnets(getExternalSubnetsUuidsSetForFixedIps(externalFixedIps));
         for (Subnets subnets : fixedIpsSubnets) {
             Uuid subnetId = subnets.getId();
-            List<Uuid> routerIds = subnets.getRouterIds();
+            List<Uuid> routerIds = new ArrayList<>();
+            routerIds = subnets.getRouterIds() != null ? new ArrayList<>(subnets.getRouterIds()) : routerIds;
             if (routerIds != null) {
                 if (subnets.getExternalNetworkId() != null
                         && subnets.getExternalNetworkId().equals(externalNetworkId)
                         && routerIds.contains(routerId)) {
                     routerIds.remove(routerId);
                     LOG.debug("Will remove routerIDs {} from external subnet {} router ID {}",
-                        subnetId, routerId);
+                        routerIds, subnetId, routerId);
                     addExternalSubnet(externalNetworkId, subnetId, routerIds);
                 }
             }
         }
     }
 
-    private Set<Uuid> getExternalSubnetsUuidsSetForFixedIps(List<ExternalFixedIps> externalFixedIps) {
+    private static Set<Uuid> getExternalSubnetsUuidsSetForFixedIps(List<ExternalFixedIps> externalFixedIps) {
         Set<Uuid> subnetsUuidsSet = new HashSet<>();
         for (ExternalFixedIps externalFixedIp : externalFixedIps) {
             subnetsUuidsSet.add(externalFixedIp.getSubnetId());
@@ -752,13 +751,64 @@ public class NeutronvpnNatManager implements AutoCloseable {
         return subnetsList;
     }
 
-    private void addExternalFixedIpToExternalIpsList(List<ExternalIps> externalIps, ExternalFixedIps fixedIps) {
+    private static void addExternalFixedIpToExternalIpsList(List<ExternalIps> externalIps, ExternalFixedIps fixedIps) {
         Uuid subnetId = fixedIps.getSubnetId();
-        String ip = fixedIps.getIpAddress().getIpv4Address().getValue();
+        String ip = fixedIps.getIpAddress().stringValue();
         ExternalIpsBuilder externalIpsBuilder = new ExternalIpsBuilder();
-        externalIpsBuilder.setKey(new ExternalIpsKey(ip, subnetId));
+        externalIpsBuilder.withKey(new ExternalIpsKey(ip, subnetId));
         externalIpsBuilder.setIpAddress(ip);
         externalIpsBuilder.setSubnetId(subnetId);
         externalIps.add(externalIpsBuilder.build());
     }
+
+    private void removeAdjacencyAndLearnedEntriesforExternalSubnet(Uuid extNetId, Uuid extSubnetId) {
+        Collection<String> extElanInterfaces = elanService.getExternalElanInterfaces(extNetId.getValue());
+        if (extElanInterfaces == null || extElanInterfaces.isEmpty()) {
+            LOG.error("No external ports attached to external network {}", extNetId.getValue());
+            return;
+        }
+
+        for (String infName : extElanInterfaces) {
+            InstanceIdentifier<VpnInterface> vpnIfIdentifier = InstanceIdentifier.builder(
+                VpnInterfaces.class).child(VpnInterface.class, new VpnInterfaceKey(infName)).build();
+            InstanceIdentifier<Adjacencies> adjacenciesIdentifier = vpnIfIdentifier.augmentation(Adjacencies.class);
+            try {
+                // Looking for existing prefix in MDSAL database
+                Optional<Adjacencies> optionalAdjacencies = SingleTransactionDataBroker.syncReadOptional(dataBroker,
+                    LogicalDatastoreType.CONFIGURATION, adjacenciesIdentifier);
+                if (optionalAdjacencies.isPresent()) {
+                    List<Adjacency> adjacencies = optionalAdjacencies.get().getAdjacency();
+                    Iterator<Adjacency> adjacencyIter = adjacencies.iterator();
+                    while (adjacencyIter.hasNext()) {
+                        Adjacency adjacency = adjacencyIter.next();
+                        if (!adjacency.getSubnetId().equals(extSubnetId)) {
+                            continue;
+                        }
+                        InstanceIdentifier<Adjacency> adjacencyIdentifier =
+                            adjacenciesIdentifier.child(Adjacency.class, new AdjacencyKey(adjacency.getIpAddress()));
+                        SingleTransactionDataBroker.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION,
+                            adjacencyIdentifier);
+                        LOG.trace("Removed Adjacency for fixedIP {} for port {} on external subnet {} ",
+                            adjacency.getIpAddress(), infName, extSubnetId);
+                        String extNetVpnName = extNetId.getValue();
+                        String learnedSrcIp = adjacency.getIpAddress().split("/")[0];
+                        InstanceIdentifier<LearntVpnVipToPort> id =
+                            NeutronvpnUtils.buildLearntVpnVipToPortIdentifier(extNetVpnName, learnedSrcIp);
+                        Optional<LearntVpnVipToPort> optionalLearntVpnVipToPort = SingleTransactionDataBroker
+                            .syncReadOptional(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
+                        if (optionalLearntVpnVipToPort.isPresent()) {
+                            neutronvpnUtils.removeLearntVpnVipToPort(extNetVpnName, learnedSrcIp);
+                            LOG.trace("Removed Learnt Entry for fixedIP {} for port {}",
+                                adjacency.getIpAddress(), infName);
+                        }
+                    }
+                }
+            } catch (TransactionCommitFailedException | ReadFailedException e) {
+                LOG.error("exception in removeAdjacencyAndLearnedEntriesforExternalSubnet for interface {}",
+                    infName, e);
+            }
+        }
+    }
+
+
 }