NETVIRT-1045 No connectivity between instances on different 30/68430/10
authorAswin Suryanarayanan <asuryana@redhat.com>
Tue, 20 Feb 2018 15:56:57 +0000 (21:26 +0530)
committerSam Hague <shague@redhat.com>
Sun, 11 Mar 2018 01:17:50 +0000 (01:17 +0000)
networks connected to the same router when using VLAN setup

A pseudo port is added to ElanDPNList  when a vlan becomes a part of the
VPN for all the dpn which has the VPN. This ensures that the patch
ports to the physical interfaces are created and necessary FIB flows are
programmed.

The pseudo port will be add a subnet becomes a part of the VPN or when
the first vpn port is added to the DPN.

Change-Id: I722ac54c33d091e7f3820a32e86422bc29511905
Signed-off-by: Aswin Suryanarayanan <asuryana@redhat.com>
vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/SubnetmapChangeListener.java
vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnFootprintService.java
vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnServiceElanDpnInterfacesListener.java [new file with mode: 0644]
vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnUtil.java

index ef2f82330946d8e6f6f6e4abe7be45fec1a51aec..16611421c0cd7dde7ebd0e4bac60d0cae115ef06 100644 (file)
@@ -21,6 +21,7 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkAttributes.NetworkType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
@@ -92,6 +93,9 @@ public class SubnetmapChangeListener extends AsyncDataTreeChangeListenerBase<Sub
                         + "subnetmapListener add for subnet {}", elanInstanceName, subnetId.getValue());
                 return;
             }
+            if (subnetmap.getNetworkType().equals(NetworkType.VLAN)) {
+                VpnUtil.addRouterPortToElanDpnListForVlaninAllDpn(vpnId.getValue(), dataBroker);
+            }
             // subnet added to VPN case upon config DS replay after reboot
             // ports added to subnet upon config DS replay after reboot are handled implicitly by subnetAddedToVpn
             // in SubnetRouteHandler
@@ -159,9 +163,9 @@ public class SubnetmapChangeListener extends AsyncDataTreeChangeListenerBase<Sub
         Uuid vpnIdInternetNew = subnetmapUpdate.getInternetVpnId();
         Uuid vpnIdInternetOld = subnetmapOriginal.getInternetVpnId();
         boolean returnValue1 = updateSubnetmapOpDataEntry(vpnIdInternetOld, vpnIdInternetNew,
-                           subnetmapUpdate, subnetmapOriginal, elanTag, updateCapableForCreation);
+                           subnetmapUpdate, subnetmapOriginal, elanTag, null, updateCapableForCreation);
         boolean returnValue2 = updateSubnetmapOpDataEntry(vpnIdOld, vpnIdNew,
-                      subnetmapUpdate, subnetmapOriginal, elanTag, updateCapableForCreation);
+                      subnetmapUpdate, subnetmapOriginal, elanTag, elanInstanceName, updateCapableForCreation);
         if (!returnValue2 || !returnValue1) {
             return;
         }
@@ -191,9 +195,13 @@ public class SubnetmapChangeListener extends AsyncDataTreeChangeListenerBase<Sub
     }
 
     private boolean updateSubnetmapOpDataEntry(Uuid vpnIdOld, Uuid vpnIdNew, Subnetmap subnetmapUpdate,
-                                    Subnetmap subnetmapOriginal, Long elanTag, boolean updateCapableForCreation) {
+                                    Subnetmap subnetmapOriginal, Long elanTag, String  elanInstanceName,
+                                    boolean updateCapableForCreation) {
         // subnet added to VPN case
         if (vpnIdNew != null && vpnIdOld == null && updateCapableForCreation) {
+            if (elanInstanceName != null && subnetmapUpdate.getNetworkType().equals(NetworkType.VLAN)) {
+                VpnUtil.addRouterPortToElanDpnListForVlaninAllDpn(vpnIdNew.getValue(), dataBroker);
+            }
             boolean isBgpVpn = !vpnIdNew.equals(subnetmapUpdate.getRouterId());
             if (!isBgpVpn) {
                 return false;
@@ -203,6 +211,10 @@ public class SubnetmapChangeListener extends AsyncDataTreeChangeListenerBase<Sub
         }
         // subnet removed from VPN case
         if (vpnIdOld != null && vpnIdNew == null) {
+            if (subnetmapOriginal.getNetworkType().equals(NetworkType.VLAN)) {
+                VpnUtil.removeRouterPortFromElanDpnListForVlanInAllDpn(elanInstanceName, subnetmapOriginal
+                        .getRouterInterfacePortId().getValue(), vpnIdOld.getValue(), dataBroker);
+            }
             boolean isBgpVpn = vpnIdOld.equals(subnetmapOriginal.getRouterId()) ? false : true;
             if (!isBgpVpn) {
                 return false;
index 49685bc72ba488396a79b5f389c1ae1894efed8a..fc0ba52726f87982bc8c7f4f6fb81d53004c6d6c 100644 (file)
@@ -24,6 +24,7 @@ import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
 import org.opendaylight.netvirt.vpnmanager.api.IVpnFootprintService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AddDpnEvent;
@@ -64,14 +65,17 @@ public class VpnFootprintService implements IVpnFootprintService {
     private final IFibManager fibManager;
     private final VpnOpDataSyncer vpnOpDataSyncer;
     private final NotificationPublishService notificationPublishService;
+    private final IInterfaceManager interfaceManager;
 
     @Inject
     public VpnFootprintService(final DataBroker dataBroker, final IFibManager fibManager,
-            final NotificationPublishService notificationPublishService, final VpnOpDataSyncer vpnOpDataSyncer) {
+            final NotificationPublishService notificationPublishService, final VpnOpDataSyncer vpnOpDataSyncer,
+            final IInterfaceManager interfaceManager) {
         this.dataBroker = dataBroker;
         this.fibManager = fibManager;
         this.vpnOpDataSyncer = vpnOpDataSyncer;
         this.notificationPublishService = notificationPublishService;
+        this.interfaceManager = interfaceManager;
     }
 
     @Override
@@ -164,6 +168,11 @@ public class VpnFootprintService implements IVpnFootprintService {
          * Informing the FIB only after writeTxn is submitted successfully.
          */
         if (newDpnOnVpn) {
+            if (VpnUtil.isVlan(dataBroker ,intfName)) {
+                if (!VpnUtil.shouldPopulateFibForVlan(dataBroker, vpnName, null, dpnId, interfaceManager)) {
+                    return;
+                }
+            }
             fibManager.populateFibOnNewDpn(dpnId, vpnId, primaryRd,
                     new DpnEnterExitVpnWorker(dpnId, vpnName, primaryRd, true /* entered */));
             LOG.info("createOrUpdateVpnToDpnList: Sent populateFib event for new dpn {} in VPN {} for interface {}",
diff --git a/vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnServiceElanDpnInterfacesListener.java b/vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnServiceElanDpnInterfacesListener.java
new file mode 100644 (file)
index 0000000..2cb16b5
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2018 Redhat and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netvirt.vpnmanager;
+
+import com.google.common.base.Optional;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+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.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
+import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
+import org.opendaylight.netvirt.fibmanager.api.IFibManager;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanDpnInterfaces;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfaces;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Singleton
+public class VpnServiceElanDpnInterfacesListener
+        extends AsyncDataTreeChangeListenerBase<DpnInterfaces, VpnServiceElanDpnInterfacesListener> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(VpnServiceElanDpnInterfacesListener.class);
+    private final DataBroker dataBroker;
+    private final IInterfaceManager interfaceManager;
+    private final IFibManager fibManager;
+    private final JobCoordinator jobCoordinator;
+    private final ManagedNewTransactionRunner txRunner;
+
+    @Inject
+    public VpnServiceElanDpnInterfacesListener(final DataBroker dataBroker, final IInterfaceManager interfaceManager,
+            final IFibManager fibManager,final JobCoordinator jobCoordinator) {
+        this.dataBroker = dataBroker;
+        this.interfaceManager = interfaceManager;
+        this.fibManager = fibManager;
+        this.jobCoordinator = jobCoordinator;
+        this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
+    }
+
+    @PostConstruct
+    public void start() {
+        registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
+    }
+
+    @Override
+    public InstanceIdentifier<DpnInterfaces> getWildCardPath() {
+        return InstanceIdentifier.builder(ElanDpnInterfaces.class).child(ElanDpnInterfacesList.class)
+                .child(DpnInterfaces.class).build();
+    }
+
+    @Override
+    protected void remove(InstanceIdentifier<DpnInterfaces> identifier, DpnInterfaces dpnInterfaces) {
+
+    }
+
+    @Override
+    protected void update(InstanceIdentifier<DpnInterfaces> identifier, DpnInterfaces original,
+            DpnInterfaces update) {
+        LOG.info("received Dpninterfaces update event for dpn {}", update.getDpId());
+        BigInteger dpnId = update.getDpId();
+        String elanInstanceName = identifier.firstKeyOf(ElanDpnInterfacesList.class).getElanInstanceName();
+        ElanInstance elanInstance = VpnUtil.getElanInstanceByName(dataBroker, elanInstanceName);
+        String vpnName = VpnUtil.getVpnNameFromElanIntanceName(dataBroker,elanInstanceName);
+        if (vpnName == null) {
+            return;
+        }
+        String primaryRd = VpnUtil.getPrimaryRd(dataBroker, vpnName);
+        if (elanInstance != null && !elanInstance.isExternal() && VpnUtil.isVlan(elanInstance)) {
+            jobCoordinator.enqueueJob(elanInstance.getElanInstanceName(), () -> {
+                return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(writeConfigTxn -> {
+                    List<String> addedInterfaces = getUpdatedInterfaceList(update.getInterfaces(),
+                            original.getInterfaces());
+                    for (String addedInterface: addedInterfaces) {
+                        if (interfaceManager.isExternalInterface(addedInterface)) {
+
+                            InstanceIdentifier<VpnToDpnList> id = VpnUtil.getVpnToDpnListIdentifier(primaryRd, dpnId);
+                            Optional<VpnToDpnList> dpnInVpn = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
+                                    id);
+                            if (!dpnInVpn.isPresent() || (dpnInVpn.get().getVpnInterfaces() != null
+                                    && dpnInVpn.get().getVpnInterfaces().size() != 1)) {
+                                return;
+                            }
+                            if (!VpnUtil.shouldPopulateFibForVlan(dataBroker, vpnName, elanInstanceName,
+                                    dpnId, interfaceManager)) {
+                                return;
+                            }
+                            long vpnId = VpnUtil.getVpnId(dataBroker, vpnName);
+                            fibManager.populateFibOnNewDpn(dpnId, vpnId, primaryRd, null);
+                            break;
+                        }
+                    }
+                    List<String> deletedInterfaces = getUpdatedInterfaceList(original.getInterfaces(),
+                            update.getInterfaces());
+                    if (!deletedInterfaces.isEmpty()) {
+                        String routerPortUuid = VpnUtil.getRouterPordIdFromElanInstance(dataBroker, elanInstanceName);
+                        if (update.getInterfaces().size() == 2 && update.getInterfaces().contains(routerPortUuid)) {
+                            VpnUtil.removeRouterPortFromElanForVlanInDpn(vpnName, dpnId, dataBroker);
+                        }
+                    }
+                }));
+            });
+        }
+
+    }
+
+    @Override
+    protected void add(InstanceIdentifier<DpnInterfaces> identifier, DpnInterfaces dpnInterfaces) {
+        BigInteger dpnId = dpnInterfaces.getDpId();
+        String elanInstanceName = identifier.firstKeyOf(ElanDpnInterfacesList.class).getElanInstanceName();
+        ElanInstance elanInstance = VpnUtil.getElanInstanceByName(dataBroker, elanInstanceName);
+        if (!VpnUtil.isVlan(elanInstance)) {
+            return;
+        }
+        String vpnName = VpnUtil.getVpnNameFromElanIntanceName(dataBroker,elanInstanceName);
+        if (vpnName == null) {
+            return;
+        }
+        VpnUtil.addRouterPortToElanForVlanInDpn(vpnName, dpnId, dataBroker);
+    }
+
+    @Override
+    protected VpnServiceElanDpnInterfacesListener getDataTreeChangeListener() {
+        return VpnServiceElanDpnInterfacesListener.this;
+    }
+
+
+    public static List<String> getUpdatedInterfaceList(List<String> updatedInterfaceList,
+            List<String> currentInterfaceList) {
+        if (updatedInterfaceList == null) {
+            return Collections.<String>emptyList();
+        }
+        List<String> newInterfaceList = new ArrayList<>(updatedInterfaceList);
+        if (currentInterfaceList == null) {
+            return newInterfaceList;
+        }
+        List<String> origInterfaceList = new ArrayList<>(currentInterfaceList);
+        for (Iterator<String> iterator = newInterfaceList.iterator(); iterator.hasNext();) {
+            String updatedInterface = iterator.next();
+            for (String currentInterface :origInterfaceList) {
+                if (updatedInterface.equals(currentInterface)) {
+                    iterator.remove();
+                }
+            }
+        }
+        return newInterfaceList;
+    }
+
+}
index 563db29009c1e6af81a66eacd74e25f763c016e6..30325ece5980b7742c60f866e0af96f70dc15513 100755 (executable)
@@ -24,9 +24,12 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Set;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
@@ -38,6 +41,7 @@ import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
 import org.opendaylight.genius.mdsalutil.FlowEntity;
 import org.opendaylight.genius.mdsalutil.FlowEntityBuilder;
 import org.opendaylight.genius.mdsalutil.InstructionInfo;
@@ -57,6 +61,7 @@ import org.opendaylight.genius.utils.ServiceIndex;
 import org.opendaylight.genius.utils.SystemPropertyReader;
 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
+import org.opendaylight.netvirt.elanmanager.api.ElanHelper;
 import org.opendaylight.netvirt.fibmanager.api.FibHelper;
 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
 import org.opendaylight.netvirt.neutronvpn.api.enums.IpVersionChoice;
@@ -105,7 +110,18 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev16041
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.TryLockInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.UnlockInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.UnlockInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanDpnInterfaces;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInterfaces;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanTagNameMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.SegmentTypeVlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesListKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfaces;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfacesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfacesKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterfaceKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.tag.name.map.ElanTagName;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.tag.name.map.ElanTagNameKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.FibEntries;
@@ -175,6 +191,7 @@ 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.napt.switches.RouterToNaptSwitch;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitchKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkAttributes.NetworkType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkMaps;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronVpnPortipPortData;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.RouterInterfacesMap;
@@ -1934,4 +1951,300 @@ public final class VpnUtil {
                 VpnUtil.getVpnInterfaceIdentifier(interfaceName), builder.build(), DEFAULT_CALLBACK);
     }
 
+    /**
+     * Adds router port for all elan network of type VLAN which is a part of vpnName in the DPN with dpnId.
+     * This will create the vlan footprint in the DPN's which are member of the VPN.
+     *
+     * @param vpnName the vpnName
+     * @param dpnId  the DPN id
+     * @param dataBroker the data Broker
+     */
+    public static void addRouterPortToElanForVlanInDpn(String vpnName, BigInteger dpnId , DataBroker dataBroker) {
+        Map<String,String> elanInstanceRouterPortMap = VpnUtil.getElanInstanceRouterPortMap(dataBroker, vpnName);
+        for (Entry<String, String> elanInstanceRouterEntry : elanInstanceRouterPortMap.entrySet()) {
+            addRouterPortToElanDpn(elanInstanceRouterEntry.getKey(), elanInstanceRouterEntry.getValue(),
+                    vpnName, dpnId, dataBroker);
+        }
+    }
+
+    /**
+     * Removes router port for all elan network of type VLAN which is a part of vpnName in the DPN with dpnId.
+     * This will remove the  vlan footprint in all the DPN's which are member of the VPN.
+     *
+     * @param vpnName the vpn name
+     * @param dpnId  the DPN id
+     * @param dataBroker the data Broker
+     */
+    public static void removeRouterPortFromElanForVlanInDpn(String vpnName, BigInteger dpnId , DataBroker dataBroker) {
+        Map<String,String> elanInstanceRouterPortMap = VpnUtil.getElanInstanceRouterPortMap(dataBroker, vpnName);
+        for (Entry<String, String> elanInstanceRouterEntry : elanInstanceRouterPortMap.entrySet()) {
+            removeRouterPortFromElanDpn(elanInstanceRouterEntry.getKey(), elanInstanceRouterEntry.getValue(),
+                    vpnName, dpnId, dataBroker);
+        }
+    }
+
+    /**
+     * Adds router port for all elan network of type VLAN which is a part of vpnName in all the DPN which has a port
+     * This will create the vlan footprint in all the DPN's which are member of the VPN.
+     *
+     * @param vpnName the vpn name
+     * @param dataBroker the data broker
+     */
+    public static void addRouterPortToElanDpnListForVlaninAllDpn(String vpnName, DataBroker dataBroker) {
+        Map<String,String> elanInstanceRouterPortMap = getElanInstanceRouterPortMap(dataBroker, vpnName);
+        Set<BigInteger> dpnList = getDpnInElan(dataBroker, elanInstanceRouterPortMap);
+        for (BigInteger dpnId : dpnList) {
+            for (Entry<String, String> elanInstanceRouterEntry : elanInstanceRouterPortMap.entrySet()) {
+                addRouterPortToElanDpn(elanInstanceRouterEntry.getKey(), elanInstanceRouterEntry.getValue(),
+                        vpnName, dpnId, dataBroker);
+            }
+        }
+    }
+
+    /**Removes router port for all elan network of type VLAN which is a part of vpnName in all the DPN which has a port
+     * This will remove the vlan footprint in all the DPN's which are member of the VPN.
+     *
+     * @param routerInterfacePortId this will add the current subnet router port id to the map for removal
+     * @param elanInstanceName the current elanstance being removed this will be added to map for removal
+     * @param vpnName the vpn name
+     * @param dataBroker the databroker
+     */
+    public static void removeRouterPortFromElanDpnListForVlanInAllDpn(String elanInstanceName,
+            String routerInterfacePortId, String vpnName, DataBroker dataBroker) {
+        Map<String,String> elanInstanceRouterPortMap = getElanInstanceRouterPortMap(dataBroker, vpnName);
+        elanInstanceRouterPortMap.put(elanInstanceName, routerInterfacePortId);
+        Set<BigInteger> dpnList = getDpnInElan(dataBroker, elanInstanceRouterPortMap);
+        for (BigInteger dpnId : dpnList) {
+            for (Entry<String, String> elanInstanceRouterEntry : elanInstanceRouterPortMap.entrySet()) {
+                removeRouterPortFromElanDpn(elanInstanceRouterEntry.getKey(), elanInstanceRouterEntry.getValue(),
+                        vpnName, dpnId, dataBroker);
+            }
+        }
+
+    }
+
+    public static Set<BigInteger> getDpnInElan(DataBroker dataBroker,  Map<String,String> elanInstanceRouterPortMap) {
+        Set<BigInteger> dpnIdSet = new HashSet<BigInteger>();
+        for (String elanInstanceName : elanInstanceRouterPortMap.keySet()) {
+            InstanceIdentifier<ElanDpnInterfacesList> elanDpnInterfaceId = getElanDpnOperationalDataPath(
+                    elanInstanceName);
+            Optional<ElanDpnInterfacesList> dpnInElanInterfaces = VpnUtil.read(dataBroker,
+                    LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId);
+            if (dpnInElanInterfaces.isPresent()) {
+                List<DpnInterfaces> dpnInterfaces = dpnInElanInterfaces.get().getDpnInterfaces();
+                for (DpnInterfaces dpnInterface : dpnInterfaces) {
+                    dpnIdSet.add(dpnInterface.getDpId());
+                }
+            }
+        }
+        return dpnIdSet;
+    }
+
+    public static void addRouterPortToElanDpn(String elanInstanceName, String routerInterfacePortId, String vpnName,
+            BigInteger dpnId, DataBroker dataBroker) {
+        InstanceIdentifier<DpnInterfaces> elanDpnInterfaceId = getElanDpnInterfaceOperationalDataPath(
+                elanInstanceName,dpnId);
+        Optional<DpnInterfaces> dpnInElanInterfaces = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
+                elanDpnInterfaceId);
+        List<String> elanInterfaceList;
+        DpnInterfaces dpnInterface;
+        if (!dpnInElanInterfaces.isPresent()) {
+            elanInterfaceList = new ArrayList<>();
+        } else {
+            dpnInterface = dpnInElanInterfaces.get();
+            elanInterfaceList = dpnInterface.getInterfaces();
+        }
+        if (!elanInterfaceList.contains(routerInterfacePortId)) {
+            elanInterfaceList.add(routerInterfacePortId);
+            dpnInterface = new DpnInterfacesBuilder().setDpId(dpnId).setInterfaces(elanInterfaceList)
+                    .setKey(new DpnInterfacesKey(dpnId)).build();
+            VpnUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL,
+                    elanDpnInterfaceId, dpnInterface);
+        }
+
+    }
+
+    public static void removeRouterPortFromElanDpn(String elanInstanceName, String routerInterfacePortId,
+            String vpnName, BigInteger dpnId, DataBroker dataBroker) {
+        InstanceIdentifier<DpnInterfaces> elanDpnInterfaceId = getElanDpnInterfaceOperationalDataPath(
+                elanInstanceName,dpnId);
+        Optional<DpnInterfaces> dpnInElanInterfaces = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
+                elanDpnInterfaceId);
+        List<String> elanInterfaceList;
+        DpnInterfaces dpnInterface;
+        if (!dpnInElanInterfaces.isPresent()) {
+            LOG.info("No interface in any dpn for {}", vpnName);
+            return;
+        } else {
+            dpnInterface = dpnInElanInterfaces.get();
+            elanInterfaceList = dpnInterface.getInterfaces();
+        }
+        if (!elanInterfaceList.contains(routerInterfacePortId)) {
+            LOG.info("Router port not present in DPN {} for VPN {}", dpnId, vpnName);
+            return;
+        }
+        elanInterfaceList.remove(routerInterfacePortId);
+        dpnInterface = new DpnInterfacesBuilder().setDpId(dpnId).setInterfaces(elanInterfaceList)
+                .setKey(new DpnInterfacesKey(dpnId)).build();
+        VpnUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL,
+                elanDpnInterfaceId, dpnInterface);
+
+    }
+
+    public static ElanInterface getElanInterfaceByElanInterfaceName(DataBroker broker, String elanInterfaceName) {
+        InstanceIdentifier<ElanInterface> elanInterfaceId = getElanInterfaceConfigurationDataPathId(elanInterfaceName);
+        return read(broker, LogicalDatastoreType.CONFIGURATION, elanInterfaceId).orNull();
+    }
+
+    public static InstanceIdentifier<ElanInterface> getElanInterfaceConfigurationDataPathId(String interfaceName) {
+        return InstanceIdentifier.builder(ElanInterfaces.class)
+                .child(ElanInterface.class, new ElanInterfaceKey(interfaceName)).build();
+    }
+
+    public static Optional<Interface> getInterface(DataBroker broker, String interfaceName) {
+        return read(broker, LogicalDatastoreType.CONFIGURATION, getInterfaceIdentifier(interfaceName));
+    }
+
+    public static DpnInterfaces getElanInterfaceInfoByElanDpn(DataBroker broker, String elanInstanceName,
+            BigInteger dpId) {
+        InstanceIdentifier<DpnInterfaces> elanDpnInterfacesId = getElanDpnInterfaceOperationalDataPath(elanInstanceName,
+                dpId);
+        return read(broker, LogicalDatastoreType.OPERATIONAL, elanDpnInterfacesId).orNull();
+    }
+
+    public static String getExternalElanInterface(DataBroker broker, String elanInstanceName, BigInteger dpnId,
+            IInterfaceManager interfaceManager) {
+        DpnInterfaces dpnInterfaces = getElanInterfaceInfoByElanDpn(broker, elanInstanceName, dpnId);
+        if (dpnInterfaces == null || dpnInterfaces.getInterfaces() == null) {
+            LOG.info("Elan {} does not have interfaces in DPN {}", elanInstanceName, dpnId);
+            return null;
+        }
+
+        for (String dpnInterface : dpnInterfaces.getInterfaces()) {
+            if (interfaceManager.isExternalInterface(dpnInterface)) {
+                return dpnInterface;
+            }
+        }
+        return null;
+    }
+
+    public static boolean isVlan(ElanInstance elanInstance) {
+        return elanInstance != null && elanInstance.getSegmentType() != null
+                && elanInstance.getSegmentType().isAssignableFrom(SegmentTypeVlan.class)
+                && elanInstance.getSegmentationId() != null && elanInstance.getSegmentationId() != 0;
+    }
+
+    public static boolean isVlan(DataBroker databroker , String interfaceName) {
+        ElanInterface elanInterface = getElanInterfaceByElanInterfaceName(databroker, interfaceName);
+        if (elanInterface == null) {
+            return false;
+        }
+        ElanInstance  elanInstance = getElanInstanceByName(databroker, elanInterface.getElanInstanceName());
+        return isVlan(elanInstance);
+    }
+
+    public static ElanInstance getElanInstanceByName(DataBroker broker, String elanInstanceName) {
+        InstanceIdentifier<ElanInstance> elanIdentifierId =
+                ElanHelper.getElanInstanceConfigurationDataPath(elanInstanceName);
+        return read(broker, LogicalDatastoreType.CONFIGURATION, elanIdentifierId).orNull();
+    }
+
+    public static String getVpnNameFromElanIntanceName(DataBroker dataBroker, String elanInstanceName) {
+        Optional<Subnetmaps> subnetMapsData =
+                read(dataBroker, LogicalDatastoreType.CONFIGURATION, buildSubnetMapsWildCardPath());
+        if (subnetMapsData.isPresent()) {
+            List<Subnetmap> subnetMapList = subnetMapsData.get().getSubnetmap();
+            if (subnetMapList != null && !subnetMapList.isEmpty()) {
+                for (Subnetmap subnet : subnetMapList) {
+                    if (subnet.getNetworkId().getValue().equals(elanInstanceName)) {
+                        if (subnet.getVpnId() != null) {
+                            return subnet.getVpnId().getValue();
+                        }
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    public static Map<String, String> getElanInstanceRouterPortMap(DataBroker dataBroker, String vpnName) {
+        Map<String, String> elanInstanceRouterPortMap = new HashMap<String, String>();
+        Optional<Subnetmaps> subnetMapsData =
+                read(dataBroker, LogicalDatastoreType.CONFIGURATION, buildSubnetMapsWildCardPath());
+        if (subnetMapsData.isPresent()) {
+            List<Subnetmap> subnetMapList = subnetMapsData.get().getSubnetmap();
+            if (subnetMapList != null && !subnetMapList.isEmpty()) {
+                for (Subnetmap subnet : subnetMapList) {
+                    if (subnet.getVpnId() != null && subnet.getVpnId().getValue().equals(vpnName)
+                            && subnet.getNetworkType().equals(NetworkType.VLAN)) {
+                        if (subnet.getRouterInterfacePortId() == null || subnet.getNetworkId() == null) {
+                            LOG.warn("The RouterInterfacePortId or NetworkId is null");
+                            continue;
+                        }
+                        String routerInterfacePortUuid = subnet.getRouterInterfacePortId().getValue();
+                        if (routerInterfacePortUuid != null && !routerInterfacePortUuid.isEmpty()) {
+                            elanInstanceRouterPortMap.put(subnet.getNetworkId().getValue(),routerInterfacePortUuid);
+                        }
+                    }
+                }
+            }
+        }
+        return elanInstanceRouterPortMap;
+    }
+
+    public static String getRouterPordIdFromElanInstance(DataBroker dataBroker, String elanInstanceName) {
+        Optional<Subnetmaps> subnetMapsData =
+                read(dataBroker, LogicalDatastoreType.CONFIGURATION, buildSubnetMapsWildCardPath());
+        if (subnetMapsData.isPresent()) {
+            List<Subnetmap> subnetMapList = subnetMapsData.get().getSubnetmap();
+            if (subnetMapList != null && !subnetMapList.isEmpty()) {
+                for (Subnetmap subnet : subnetMapList) {
+                    if (subnet.getNetworkId().getValue().equals(elanInstanceName)) {
+                        if (subnet.getRouterInterfacePortId() != null) {
+                            return subnet.getRouterInterfacePortId().getValue();
+                        }
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    public static boolean shouldPopulateFibForVlan(DataBroker dataBroker, String vpnName, String elanInstanceName,
+            BigInteger dpnId, IInterfaceManager interfaceManager) {
+        Map<String,String> elanInstanceRouterPortMap = VpnUtil
+                .getElanInstanceRouterPortMap(dataBroker, vpnName);
+        boolean shouldPopulateFibForVlan = false;
+        if (!elanInstanceRouterPortMap.isEmpty()) {
+            shouldPopulateFibForVlan = true;
+        }
+        for (Entry<String, String> elanInstanceRouterEntry : elanInstanceRouterPortMap
+                .entrySet()) {
+            String currentElanInstance = elanInstanceRouterEntry.getKey();
+            if (elanInstanceName != null && elanInstanceName.equals(currentElanInstance)) {
+                continue;
+            }
+            String externalinterface = VpnUtil.getExternalElanInterface(dataBroker,
+                    currentElanInstance ,dpnId,
+                    interfaceManager);
+            if (externalinterface == null) {
+                shouldPopulateFibForVlan = false;
+                break;
+            }
+        }
+        return shouldPopulateFibForVlan;
+    }
+
+    public static InstanceIdentifier<DpnInterfaces> getElanDpnInterfaceOperationalDataPath(String elanInstanceName,
+            BigInteger dpId) {
+        return InstanceIdentifier.builder(ElanDpnInterfaces.class)
+                .child(ElanDpnInterfacesList.class, new ElanDpnInterfacesListKey(elanInstanceName))
+                .child(DpnInterfaces.class, new DpnInterfacesKey(dpId)).build();
+    }
+
+    public static InstanceIdentifier<ElanDpnInterfacesList> getElanDpnOperationalDataPath(String elanInstanceName) {
+        return InstanceIdentifier.builder(ElanDpnInterfaces.class)
+                .child(ElanDpnInterfacesList.class, new ElanDpnInterfacesListKey(elanInstanceName))
+                .build();
+    }
 }