BUG 6841: Few Remote flows not deleted on DPNs
[netvirt.git] / vpnservice / vpnmanager / vpnmanager-impl / src / main / java / org / opendaylight / netvirt / vpnmanager / VpnInterfaceManager.java
index ef019d8b8425d694689261771681bb4a141e00af..6963239076acda6a7c5863a4ad311d497872d819 100644 (file)
@@ -32,14 +32,12 @@ import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
 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.AsyncDataBroker.DataChangeScope;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
-import org.opendaylight.genius.mdsalutil.AbstractDataChangeListener;
 import org.opendaylight.genius.mdsalutil.ActionInfo;
 import org.opendaylight.genius.mdsalutil.ActionType;
 import org.opendaylight.genius.mdsalutil.FlowEntity;
@@ -55,6 +53,7 @@ import org.opendaylight.genius.utils.ServiceIndex;
 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
+import org.opendaylight.netvirt.vpnmanager.intervpnlink.InterVpnLinkUtil;
 import org.opendaylight.netvirt.vpnmanager.utilities.InterfaceUtils;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnAfConfig;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
@@ -64,7 +63,6 @@ import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev14081
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey;
 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.VpnInterfaceBuilder;
 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.interfaces.rev140508.InterfacesState;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
@@ -81,6 +79,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.Se
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServices;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.LockManagerService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
@@ -120,6 +119,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neu
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.remove.dpn.event.RemoveEventData;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.remove.dpn.event.RemoveEventDataBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnListBuilder;
@@ -136,9 +136,9 @@ import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface> implements AutoCloseable {
+public class VpnInterfaceManager extends AsyncDataTreeChangeListenerBase<VpnInterface, VpnInterfaceManager>
+        implements AutoCloseable {
     private static final Logger LOG = LoggerFactory.getLogger(VpnInterfaceManager.class);
-    private ListenerRegistration<DataChangeListener> listenerRegistration;
     private final DataBroker dataBroker;
     private final IBgpManager bgpManager;
     private final IFibManager fibManager;
@@ -158,7 +158,7 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
                                final IFibManager fibManager,
                                final OdlInterfaceRpcService ifaceMgrRpcService,
                                final NotificationPublishService notificationPublishService) {
-        super(VpnInterface.class);
+        super(VpnInterface.class, VpnInterfaceManager.class);
         this.dataBroker = dataBroker;
         this.bgpManager = bgpManager;
         this.arpManager = arpManager;
@@ -171,23 +171,20 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
 
     public void start() {
         LOG.info("{} start", getClass().getSimpleName());
-        listenerRegistration = dataBroker.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
-                getWildCardPath(), this, DataChangeScope.SUBTREE);
+        registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
     }
 
-    private InstanceIdentifier<VpnInterface> getWildCardPath() {
+    @Override
+    protected InstanceIdentifier<VpnInterface> getWildCardPath() {
         return InstanceIdentifier.create(VpnInterfaces.class).child(VpnInterface.class);
     }
 
     @Override
-    public void close() throws Exception {
-        if (listenerRegistration != null) {
-            listenerRegistration.close();
-            listenerRegistration = null;
-        }
-        LOG.info("{} close", getClass().getSimpleName());
+    protected VpnInterfaceManager getDataTreeChangeListener() {
+        return VpnInterfaceManager.this;
     }
 
+
     private InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> getInterfaceListenerPath() {
         return InstanceIdentifier.create(InterfacesState.class)
                 .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.class);
@@ -525,28 +522,44 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
 
                         instructions.add(MDSALUtil.buildAndGetWriteMetadaInstruction(
                                 MetaDataUtil.getVpnIdMetadata(vpnId), MetaDataUtil.METADATA_MASK_VRFID, ++instructionKey));
-                        instructions.add(MDSALUtil.buildAndGetGotoTableInstruction(NwConstants.L3_FIB_TABLE, ++instructionKey));
+                        instructions.add(MDSALUtil.buildAndGetGotoTableInstruction(NwConstants.L3_GW_MAC_TABLE, ++instructionKey));
 
                         BoundServices
                                 serviceInfo =
                                 InterfaceUtils.getBoundServices(String.format("%s.%s.%s", "vpn",vpnInstanceName, vpnInterfaceName),
-                                        NwConstants.L3VPN_SERVICE_INDEX, priority,
+                                        ServiceIndex.getIndex(NwConstants.L3VPN_SERVICE_NAME, NwConstants.L3VPN_SERVICE_INDEX), priority,
                                         NwConstants.COOKIE_VM_INGRESS_TABLE, instructions);
                         writeTxn.put(LogicalDatastoreType.CONFIGURATION,
-                                InterfaceUtils.buildServiceId(vpnInterfaceName, NwConstants.L3VPN_SERVICE_INDEX), serviceInfo, true);
+                                InterfaceUtils.buildServiceId(vpnInterfaceName, ServiceIndex.getIndex(NwConstants.L3VPN_SERVICE_NAME, NwConstants.L3VPN_SERVICE_INDEX)), serviceInfo, true);
                         List<ListenableFuture<Void>> futures = new ArrayList<ListenableFuture<Void>>();
                         futures.add(writeTxn.submit());
                         return futures;
                     }
                 });
-        makeArpFlow(dpId, NwConstants.L3VPN_SERVICE_INDEX, lPortTag, vpnInterfaceName,
-                vpnId, ArpReplyOrRequest.REQUEST, NwConstants.ADD_FLOW, writeInvTxn);
-        makeArpFlow(dpId, NwConstants.L3VPN_SERVICE_INDEX, lPortTag, vpnInterfaceName,
-                vpnId, ArpReplyOrRequest.REPLY, NwConstants.ADD_FLOW, writeInvTxn);
+        setupGwMacIfExternalVpn(dpId, vpnInterfaceName, vpnId, writeInvTxn, NwConstants.ADD_FLOW);
+    }
 
+    private void setupGwMacIfExternalVpn(BigInteger dpnId, String interfaceName, long vpnId,
+            WriteTransaction writeInvTxn, int addOrRemove) {
+        InstanceIdentifier<VpnIds> vpnIdsInstanceIdentifier = VpnUtil.getVpnIdToVpnInstanceIdentifier(vpnId);
+        Optional<VpnIds> vpnIdsOptional = VpnUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIdsInstanceIdentifier);
+        if (vpnIdsOptional.isPresent() && vpnIdsOptional.get().isExternalVpn()) {
+            Optional<String> gwMacAddressOptional = InterfaceUtils.getMacAddressForInterface(dataBroker, interfaceName);
+            if (!gwMacAddressOptional.isPresent()) {
+                LOG.error("Failed to get gwMacAddress for interface {}", interfaceName);
+                return;
+            }
+            String gwMacAddress = gwMacAddressOptional.get();
+            FlowEntity flowEntity = VpnUtil.buildL3vpnGatewayFlow(dpnId, gwMacAddress, vpnId);
+            if (addOrRemove == NwConstants.ADD_FLOW) {
+                mdsalManager.addFlowToTx(flowEntity, writeInvTxn);
+            } else if (addOrRemove == NwConstants.DEL_FLOW) {
+                mdsalManager.removeFlowToTx(flowEntity, writeInvTxn);
+            }
+        }
     }
 
-    private void processVpnInterfaceAdjacencies(BigInteger dpnId, String vpnName, String interfaceName,
+    protected void processVpnInterfaceAdjacencies(BigInteger dpnId, String vpnName, String interfaceName,
                                                 WriteTransaction writeConfigTxn,
                                                 WriteTransaction writeOperTxn) {
         InstanceIdentifier<VpnInterface> identifier = VpnUtil.getVpnInterfaceIdentifier(interfaceName);
@@ -567,7 +580,7 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
                 return;
             }
 
-            List<VpnInstance> vpnsToImportRoute = getVpnsImportingMyRoute(vpnName);
+            List<VpnInstanceOpDataEntry> vpnsToImportRoute = getVpnsImportingMyRoute(vpnName);
 
             LOG.trace("NextHops for interface {} are {}", interfaceName, nextHops);
             for (Adjacency nextHop : nextHops) {
@@ -575,6 +588,10 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
                 long label = VpnUtil.getUniqueId(idManager, VpnConstants.VPN_IDPOOL_NAME,
                         VpnUtil.getNextHopLabelKey((rd == null) ? vpnName
                                 : rd, prefix));
+                if (label == VpnConstants.INVALID_LABEL) {
+                    LOG.error("Unable to fetch label from Id Manager. Bailing out of processing add/update of vpn interface {} for vpn {}", interfaceName, vpnName);
+                    return;
+                }
                 List<String> adjNextHop = nextHop.getNextHopIpList();
                 value.add(new AdjacencyBuilder(nextHop).setLabel(label).setNextHopIpList(
                         (adjNextHop != null && !adjNextHop.isEmpty()) ? adjNextHop : Arrays.asList(nextHopIp))
@@ -612,8 +629,8 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
                             interfaceName, null,false, rd, writeOperTxn);
                     addPrefixToBGP(rd, nextHop.getIpAddress(), nextHopIp, label, writeConfigTxn);
                     //TODO: ERT - check for VPNs importing my route
-                    for (VpnInstance vpn : vpnsToImportRoute) {
-                        String vpnRd = vpn.getIpv4Family().getRouteDistinguisher();
+                    for (VpnInstanceOpDataEntry vpn : vpnsToImportRoute) {
+                        String vpnRd = vpn.getVrfId();
                         if (vpnRd != null) {
                             LOG.debug("Exporting route with rd {} prefix {} nexthop {} label {} to VPN {}", vpnRd, nextHop.getIpAddress(), nextHopIp, label, vpn);
                             fibManager.addOrUpdateFibEntry(dataBroker, vpnRd, nextHop.getIpAddress(), Arrays.asList(nextHopIp), (int) label,
@@ -629,88 +646,88 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
         }
     }
 
-    private List<VpnInstance> getVpnsImportingMyRoute(final String vpnName) {
-        List<VpnInstance> vpnsToImportRoute = new ArrayList<>();
+    private List<VpnInstanceOpDataEntry> getVpnsImportingMyRoute(final String vpnName) {
+        List<VpnInstanceOpDataEntry> vpnsToImportRoute = new ArrayList<>();
 
-        InstanceIdentifier<VpnInstance> id = InstanceIdentifier.builder(VpnInstances.class)
-                .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
-        Optional<VpnInstance> optVpnInstance = VpnUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
-        final VpnInstance vpnInstance;
-        if (optVpnInstance.isPresent()) {
-            vpnInstance = optVpnInstance.get();
-        } else {
-            LOG.debug("Could not retrieve vpn instance {} to check for vpns importing the routes", vpnName);
+        final String vpnRd = VpnUtil.getVpnRd(dataBroker, vpnName);
+        final VpnInstanceOpDataEntry vpnInstanceOpDataEntry = VpnUtil.getVpnInstanceOpData(dataBroker, vpnRd);
+        if (vpnInstanceOpDataEntry == null) {
+            LOG.debug("Could not retrieve vpn instance op data for {} to check for vpns importing the routes", vpnName);
             return vpnsToImportRoute;
         }
 
-        Predicate<VpnInstance> excludeVpn = new Predicate<VpnInstance>() {
+        Predicate<VpnInstanceOpDataEntry> excludeVpn = new Predicate<VpnInstanceOpDataEntry>() {
             @Override
-            public boolean apply(VpnInstance input) {
+            public boolean apply(VpnInstanceOpDataEntry input) {
+                if (input.getVpnInstanceName() == null) {
+                    LOG.error("Received vpn instance without identity");
+                    return false;
+                }
                 return !input.getVpnInstanceName().equals(vpnName);
             }
         };
 
-        Predicate<VpnInstance> matchRTs = new Predicate<VpnInstance>() {
+        Predicate<VpnInstanceOpDataEntry> matchRTs = new Predicate<VpnInstanceOpDataEntry>() {
             @Override
-            public boolean apply(VpnInstance input) {
-                Iterable<String> commonRTs = intersection(getRts(vpnInstance, VpnTarget.VrfRTType.ExportExtcommunity),
+            public boolean apply(VpnInstanceOpDataEntry input) {
+                Iterable<String> commonRTs = intersection(getRts(vpnInstanceOpDataEntry, VpnTarget.VrfRTType.ExportExtcommunity),
                         getRts(input, VpnTarget.VrfRTType.ImportExtcommunity));
                 return Iterators.size(commonRTs.iterator()) > 0;
             }
         };
 
-        Function<VpnInstance, String> toInstanceName = new Function<VpnInstance, String>() {
+        Function<VpnInstanceOpDataEntry, String> toInstanceName = new Function<VpnInstanceOpDataEntry, String>() {
             @Override
-            public String apply(VpnInstance vpnInstance) {
+            public String apply(VpnInstanceOpDataEntry vpnInstance) {
                 //return vpnInstance.getVpnInstanceName();
-                return vpnInstance.getIpv4Family().getRouteDistinguisher();
+                return vpnInstance.getVrfId();
             }
         };
 
-        vpnsToImportRoute = FluentIterable.from(VpnUtil.getAllVpnInstance(dataBroker)).
+        vpnsToImportRoute = FluentIterable.from(VpnUtil.getAllVpnInstanceOpData(dataBroker)).
                 filter(excludeVpn).
                 filter(matchRTs).toList();
         return vpnsToImportRoute;
     }
 
-    private List<VpnInstance> getVpnsExportingMyRoute(final String vpnName) {
-        List<VpnInstance> vpnsToExportRoute = new ArrayList<>();
+    private List<VpnInstanceOpDataEntry> getVpnsExportingMyRoute(final String vpnName) {
+        List<VpnInstanceOpDataEntry> vpnsToExportRoute = new ArrayList<>();
 
-        InstanceIdentifier<VpnInstance> id = InstanceIdentifier.builder(VpnInstances.class)
-                .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
-        Optional<VpnInstance> optVpnInstance = VpnUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
-        final VpnInstance vpnInstance;
-        if (optVpnInstance.isPresent()) {
-            vpnInstance = optVpnInstance.get();
-        } else {
-            LOG.debug("Could not retrieve vpn instance {} to check for vpns exporting the routes", vpnName);
+        String vpnRd = VpnUtil.getVpnRd(dataBroker, vpnName);
+        final VpnInstanceOpDataEntry vpnInstanceOpDataEntry = VpnUtil.getVpnInstanceOpData(dataBroker, vpnRd);
+        if (vpnInstanceOpDataEntry == null) {
+            LOG.debug("Could not retrieve vpn instance op data for {} to check for vpns exporting the routes", vpnName);
             return vpnsToExportRoute;
         }
 
-        Predicate<VpnInstance> excludeVpn = new Predicate<VpnInstance>() {
+        Predicate<VpnInstanceOpDataEntry> excludeVpn = new Predicate<VpnInstanceOpDataEntry>() {
             @Override
-            public boolean apply(VpnInstance input) {
+            public boolean apply(VpnInstanceOpDataEntry input) {
+                if (input.getVpnInstanceName() == null) {
+                    LOG.error("Received vpn instance without identity");
+                    return false;
+                }
                 return !input.getVpnInstanceName().equals(vpnName);
             }
         };
 
-        Predicate<VpnInstance> matchRTs = new Predicate<VpnInstance>() {
+        Predicate<VpnInstanceOpDataEntry> matchRTs = new Predicate<VpnInstanceOpDataEntry>() {
             @Override
-            public boolean apply(VpnInstance input) {
-                Iterable<String> commonRTs = intersection(getRts(vpnInstance, VpnTarget.VrfRTType.ImportExtcommunity),
+            public boolean apply(VpnInstanceOpDataEntry input) {
+                Iterable<String> commonRTs = intersection(getRts(vpnInstanceOpDataEntry, VpnTarget.VrfRTType.ImportExtcommunity),
                         getRts(input, VpnTarget.VrfRTType.ExportExtcommunity));
                 return Iterators.size(commonRTs.iterator()) > 0;
             }
         };
 
-        Function<VpnInstance, String> toInstanceName = new Function<VpnInstance, String>() {
+        Function<VpnInstanceOpDataEntry, String> toInstanceName = new Function<VpnInstanceOpDataEntry, String>() {
             @Override
-            public String apply(VpnInstance vpnInstance) {
+            public String apply(VpnInstanceOpDataEntry vpnInstance) {
                 return vpnInstance.getVpnInstanceName();
             }
         };
 
-        vpnsToExportRoute = FluentIterable.from(VpnUtil.getAllVpnInstance(dataBroker)).
+        vpnsToExportRoute = FluentIterable.from(VpnUtil.getAllVpnInstanceOpData(dataBroker)).
                 filter(excludeVpn).
                 filter(matchRTs).toList();
         return vpnsToExportRoute;
@@ -726,25 +743,20 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
         };
     }
 
-    private List<String> getRts(VpnInstance vpnInstance, VpnTarget.VrfRTType rtType) {
+    private List<String> getRts(VpnInstanceOpDataEntry vpnInstance, VpnTarget.VrfRTType rtType) {
         String name = vpnInstance.getVpnInstanceName();
         List<String> rts = new ArrayList<>();
-        VpnAfConfig vpnConfig = vpnInstance.getIpv4Family();
-        if (vpnConfig == null) {
-            LOG.trace("vpn config is not available for {}", name);
-            return rts;
-        }
-        VpnTargets targets = vpnConfig.getVpnTargets();
+        org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnTargets targets = vpnInstance.getVpnTargets();
         if (targets == null) {
             LOG.trace("vpn targets not available for {}", name);
             return rts;
         }
-        List<VpnTarget> vpnTargets = targets.getVpnTarget();
+        List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpntargets.VpnTarget> vpnTargets = targets.getVpnTarget();
         if (vpnTargets == null) {
             LOG.trace("vpnTarget values not available for {}", name);
             return rts;
         }
-        for (VpnTarget target : vpnTargets) {
+        for (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpntargets.VpnTarget target : vpnTargets) {
             //TODO: Check for RT type is Both
             if(target.getVrfRTType().equals(rtType) ||
                     target.getVrfRTType().equals(VpnTarget.VrfRTType.Both)) {
@@ -754,7 +766,7 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
         }
         return rts;
     }
-
+    
     private List<String> getExportRts(VpnInstance vpnInstance) {
         List<String> exportRts = new ArrayList<>();
         VpnAfConfig vpnConfig = vpnInstance.getIpv4Family();
@@ -769,74 +781,6 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
         return exportRts;
     }
 
-    private void makeArpFlow(BigInteger dpId,short sIndex, int lPortTag, String vpnInterfaceName,
-                             long vpnId, ArpReplyOrRequest replyOrRequest, int addOrRemoveFlow,
-                             WriteTransaction writeConfigTxn){
-        List<MatchInfo> matches = new ArrayList<MatchInfo>();
-        BigInteger metadata = MetaDataUtil.getMetaDataForLPortDispatcher(lPortTag, ++sIndex, MetaDataUtil.getVpnIdMetadata(vpnId));
-        BigInteger metadataMask = MetaDataUtil.getMetaDataMaskForLPortDispatcher(MetaDataUtil.METADATA_MASK_SERVICE_INDEX,
-                MetaDataUtil.METADATA_MASK_LPORT_TAG, MetaDataUtil.METADATA_MASK_VRFID);
-
-        // Matching Arp reply flows
-        matches.add(new MatchInfo(MatchFieldType.eth_type, new long[] { NwConstants.ETHTYPE_ARP }));
-        matches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
-                metadata, metadataMask }));
-
-        matches.add(new MatchInfo(MatchFieldType.arp_op, new long[] { replyOrRequest.getArpOperation() }));
-
-        // Instruction to punt to controller
-        List<InstructionInfo> instructions = new ArrayList<InstructionInfo>();
-        List<ActionInfo> actionsInfos = new ArrayList<ActionInfo>();
-        actionsInfos.add(new ActionInfo(ActionType.punt_to_controller, new String[] {}));
-        actionsInfos.add(new ActionInfo(ActionType.nx_resubmit, new String[]{
-                Short.toString(NwConstants.LPORT_DISPATCHER_TABLE)}));
-
-        instructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
-
-        // Install the flow entry in L3_INTERFACE_TABLE
-        String flowRef = VpnUtil.getFlowRef(dpId, NwConstants.L3_INTERFACE_TABLE,
-                NwConstants.ETHTYPE_ARP, lPortTag, replyOrRequest.getArpOperation());
-        FlowEntity flowEntity;
-        flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.L3_INTERFACE_TABLE, flowRef,
-                NwConstants.DEFAULT_ARP_FLOW_PRIORITY, replyOrRequest.getName(), 0, 0,
-                VpnUtil.getCookieArpFlow(lPortTag), matches, instructions);
-
-        Flow flow = flowEntity.getFlowBuilder().build();
-        String flowId = flowEntity.getFlowId();
-        FlowKey flowKey = new FlowKey( new FlowId(flowId));
-        Node nodeDpn = buildDpnNode(dpId);
-
-        InstanceIdentifier<Flow> flowInstanceId = InstanceIdentifier.builder(Nodes.class)
-                .child(Node.class, nodeDpn.getKey()).augmentation(FlowCapableNode.class)
-                .child(Table.class, new TableKey(flow.getTableId())).child(Flow.class, flowKey).build();
-
-        if (writeConfigTxn != null) {
-            if (addOrRemoveFlow == NwConstants.ADD_FLOW) {
-                LOG.debug("Creating ARP Flow for interface {}", vpnInterfaceName);
-                writeConfigTxn.put(LogicalDatastoreType.CONFIGURATION, flowInstanceId, flow, true);
-            } else {
-                LOG.debug("Deleting ARP Flow for interface {}", vpnInterfaceName);
-                writeConfigTxn.delete(LogicalDatastoreType.CONFIGURATION, flowInstanceId);
-            }
-        } else {
-            if (addOrRemoveFlow == NwConstants.ADD_FLOW) {
-                LOG.debug("Creating ARP Flow for interface {}",vpnInterfaceName);
-                mdsalManager.installFlow(flowEntity);
-            } else {
-                LOG.debug("Deleting ARP Flow for interface {}",vpnInterfaceName);
-                mdsalManager.removeFlow(flowEntity);
-            }
-        }
-    }
-
-    //TODO: How to handle the below code, its a copy paste from MDSALManager.java
-    private Node buildDpnNode(BigInteger dpnId) {
-        NodeId nodeId = new NodeId("openflow:" + dpnId);
-        Node nodeDpn = new NodeBuilder().setId(nodeId).setKey(new NodeKey(nodeId)).build();
-
-        return nodeDpn;
-    }
-
     private String getRouteDistinguisher(String vpnName) {
         InstanceIdentifier<VpnInstance> id = InstanceIdentifier.builder(VpnInstances.class)
                 .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
@@ -844,7 +788,7 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
         String rd = null;
         if(vpnInstance.isPresent()) {
             VpnInstance instance = vpnInstance.get();
-            VpnAfConfig config = instance.getIpv4Family();
+            org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnAfConfig config = instance.getIpv4Family();
             rd = config.getRouteDistinguisher();
         }
         return rd;
@@ -1020,10 +964,10 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
     }
 
     void handleVpnsExportingRoutes(String vpnName, String vpnRd) {
-        List<VpnInstance> vpnsToExportRoute = getVpnsExportingMyRoute(vpnName);
-        for (VpnInstance vpn : vpnsToExportRoute) {
-            String rd = vpn.getIpv4Family().getRouteDistinguisher();
-            List<VrfEntry> vrfEntries = VpnUtil.getAllVrfEntries(dataBroker, vpn.getIpv4Family().getRouteDistinguisher());
+        List<VpnInstanceOpDataEntry> vpnsToExportRoute = getVpnsExportingMyRoute(vpnName);
+        for (VpnInstanceOpDataEntry vpn : vpnsToExportRoute) {
+            String rd = vpn.getVrfId();
+            List<VrfEntry> vrfEntries = VpnUtil.getAllVrfEntries(dataBroker, vpn.getVrfId());
             WriteTransaction writeConfigTxn = dataBroker.newWriteOnlyTransaction();
             if (vrfEntries != null) {
                 for (VrfEntry vrfEntry : vrfEntries) {
@@ -1038,7 +982,7 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
                         for (String nh : nextHops) {
                             if (route != null) {
                                 LOG.info("Importing subnet route fib entry rd {} prefix {} nexthop {} label {} to vpn {}", vpnRd, prefix, nh, label, vpn.getVpnInstanceName());
-                                importSubnetRouteForNewVpn(rd, prefix, nh, (int)label, route, writeConfigTxn);
+                                importSubnetRouteForNewVpn(vpnRd, prefix, nh, (int)label, route, writeConfigTxn);
                             } else {
                                 LOG.info("Importing fib entry rd {} prefix {} nexthop {} label {} to vpn {}", vpnRd, prefix, nh, label, vpn.getVpnInstanceName());
                                 fibManager.addOrUpdateFibEntry(dataBroker, vpnRd, prefix, Arrays.asList(nh), (int)label,
@@ -1051,7 +995,7 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
                 }
                 writeConfigTxn.submit();
             } else {
-                LOG.info("No vrf entries to import from vpn {} with rd {}", vpn.getVpnInstanceName(), vpn.getIpv4Family().getRouteDistinguisher());
+                LOG.info("No vrf entries to import from vpn {} with rd {}", vpn.getVpnInstanceName(), vpn.getVrfId());
             }
         }
     }
@@ -1215,12 +1159,12 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
                             fibManager.removeOrUpdateFibEntry(dataBroker, vpnName, nextHop.getIpAddress(), nh, writeConfigTxn);
                         }
                     } else {
-                        List<VpnInstance> vpnsToImportRoute = getVpnsImportingMyRoute(vpnName);
+                        List<VpnInstanceOpDataEntry> vpnsToImportRoute = getVpnsImportingMyRoute(vpnName);
                         for (String nh : nhList) {
                             //IRT: remove routes from other vpns importing it
                             removePrefixFromBGP(rd, nextHop.getIpAddress(), nh, writeConfigTxn);
-                            for (VpnInstance vpn : vpnsToImportRoute) {
-                                String vpnRd = vpn.getIpv4Family().getRouteDistinguisher();
+                            for (VpnInstanceOpDataEntry vpn : vpnsToImportRoute) {
+                                String vpnRd = vpn.getVrfId();
                                 if (vpnRd != null) {
                                     LOG.info("Removing Exported route with rd {} prefix {} from VPN {}", vpnRd, nextHop.getIpAddress(), vpn.getVpnInstanceName());
                                     fibManager.removeOrUpdateFibEntry(dataBroker, vpnRd, nextHop.getIpAddress(), nh, writeConfigTxn);
@@ -1255,7 +1199,7 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
                             WriteTransaction writeTxn = dataBroker.newWriteOnlyTransaction();
                             writeTxn.delete(LogicalDatastoreType.CONFIGURATION,
                                     InterfaceUtils.buildServiceId(vpnInterfaceName,
-                                            NwConstants.L3VPN_SERVICE_INDEX));
+                                            ServiceIndex.getIndex(NwConstants.L3VPN_SERVICE_NAME, NwConstants.L3VPN_SERVICE_INDEX)));
 
                             List<ListenableFuture<Void>> futures = new ArrayList<ListenableFuture<Void>>();
                             futures.add(writeTxn.submit());
@@ -1264,10 +1208,7 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
                     });
         }
         long vpnId = VpnUtil.getVpnId(dataBroker, vpnInstanceName);
-        makeArpFlow(dpId, l3vpn_service_index, lPortTag, vpnInterfaceName,
-                vpnId, ArpReplyOrRequest.REQUEST, NwConstants.DEL_FLOW, writeInvTxn);
-        makeArpFlow(dpId, l3vpn_service_index, lPortTag, vpnInterfaceName,
-                vpnId, ArpReplyOrRequest.REPLY, NwConstants.DEL_FLOW, writeInvTxn);
+        setupGwMacIfExternalVpn(dpId, vpnInterfaceName, vpnId, writeConfigTxn, NwConstants.DEL_FLOW);
     }
 
 
@@ -1289,13 +1230,15 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
         String oldVpnName = original.getVpnInstanceName();
         String newVpnName = update.getVpnInstanceName();
         BigInteger dpnId = update.getDpnId();
-        List<Adjacency> oldAdjs = original.getAugmentation(Adjacencies.class).getAdjacency();
-        List<Adjacency> newAdjs = update.getAugmentation(Adjacencies.class).getAdjacency();
-        if (oldAdjs == null) {
-            oldAdjs = new ArrayList<>();
+        List<Adjacency> oldAdjsList = new ArrayList<>();
+        List<Adjacency> newAdjsList = new ArrayList<>();
+        Adjacencies oldAdjs = original.getAugmentation(Adjacencies.class);
+        Adjacencies newAdjs = update.getAugmentation(Adjacencies.class);
+        if (oldAdjs != null) {
+            oldAdjsList = oldAdjs.getAdjacency();
         }
-        if (newAdjs == null) {
-            newAdjs = new ArrayList<>();
+        if (newAdjs != null) {
+            newAdjsList = newAdjs.getAdjacency();
         }
         //handles switching between <internal VPN - external VPN>
         if (!oldVpnName.equals(newVpnName)) {
@@ -1305,16 +1248,16 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
         }
         //handle both addition and removal of adjacencies
         //currently, new adjacency may be an extra route
-        if (!oldAdjs.equals(newAdjs)) {
-            for (Adjacency adj : newAdjs) {
-                if (oldAdjs.contains(adj)) {
-                    oldAdjs.remove(adj);
+        if (!oldAdjsList.equals(newAdjsList)) {
+            for (Adjacency adj : newAdjsList) {
+                if (oldAdjsList.contains(adj)) {
+                    oldAdjsList.remove(adj);
                 } else {
                     // add new adjacency - right now only extra route will hit this path
-                    addNewAdjToVpnInterface(identifier, adj, dpnId);
+                    addNewAdjToVpnInterface(identifier, adj);
                 }
             }
-            for (Adjacency adj : oldAdjs) {
+            for (Adjacency adj : oldAdjsList) {
                 delAdjFromVpnInterface(identifier, adj, dpnId);
             }
         }
@@ -1396,7 +1339,7 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
         }
     }
 
-    public synchronized void addSubnetRouteFibEntryToDS(String rd, String vpnName, String prefix, String nextHop, int label,
+    public void addSubnetRouteFibEntryToDS(String rd, String vpnName, String prefix, String nextHop, int label,
                                                         long elantag, BigInteger dpnId, WriteTransaction writeTxn) {
         SubnetRoute route = new SubnetRouteBuilder().setElantag(elantag).build();
         RouteOrigin origin = RouteOrigin.STATIC; // Only case when a route is considered as directly connected
@@ -1424,15 +1367,15 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
             VpnUtil.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, vrfTableId, vrfTableNew);
         }
 
-        List<VpnInstance> vpnsToImportRoute = getVpnsImportingMyRoute(vpnName);
+        List<VpnInstanceOpDataEntry> vpnsToImportRoute = getVpnsImportingMyRoute(vpnName);
         if (vpnsToImportRoute.size() > 0) {
             VrfEntry importingVrfEntry = new VrfEntryBuilder().setDestPrefix(prefix).setNextHopAddressList(Arrays.asList(nextHop))
                     .setLabel((long) label).setOrigin(RouteOrigin.SELF_IMPORTED.getValue())
                     .addAugmentation(SubnetRoute.class, route).build();
             List<VrfEntry> importingVrfEntryList = Arrays.asList(importingVrfEntry);
-            for (VpnInstance vpnInstance : vpnsToImportRoute) {
+            for (VpnInstanceOpDataEntry vpnInstance : vpnsToImportRoute) {
                 LOG.info("Exporting subnet route rd {} prefix {} nexthop {} label {} to vpn {}", rd, prefix, nextHop, label, vpnInstance.getVpnInstanceName());
-                String importingRd = vpnInstance.getIpv4Family().getRouteDistinguisher();
+                String importingRd = vpnInstance.getVrfId();
                 InstanceIdentifier<VrfTables> importingVrfTableId = InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(importingRd)).build();
                 VrfTables importingVrfTable = new VrfTablesBuilder().setRouteDistinguisher(importingRd).setVrfEntry(importingVrfEntryList).build();
                 if (writeTxn != null) {
@@ -1465,17 +1408,17 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
         }
     }
 
-    public synchronized void deleteSubnetRouteFibEntryFromDS(String rd, String prefix, String vpnName){
+    public void deleteSubnetRouteFibEntryFromDS(String rd, String prefix, String vpnName){
         fibManager.removeFibEntry(dataBroker, rd, prefix, null);
-        List<VpnInstance> vpnsToImportRoute = getVpnsImportingMyRoute(vpnName);
-        for (VpnInstance vpnInstance : vpnsToImportRoute) {
-            String importingRd = vpnInstance.getIpv4Family().getRouteDistinguisher();
+        List<VpnInstanceOpDataEntry> vpnsToImportRoute = getVpnsImportingMyRoute(vpnName);
+        for (VpnInstanceOpDataEntry vpnInstance : vpnsToImportRoute) {
+            String importingRd = vpnInstance.getVrfId();
             LOG.info("Deleting imported subnet route rd {} prefix {} from vpn {}", rd, prefix, vpnInstance.getVpnInstanceName());
             fibManager.removeFibEntry(dataBroker, importingRd, prefix, null);
         }
     }
 
-    protected void addNewAdjToVpnInterface(InstanceIdentifier<VpnInterface> identifier, Adjacency adj, BigInteger dpnId) {
+    protected void addNewAdjToVpnInterface(InstanceIdentifier<VpnInterface> identifier, Adjacency adj) {
 
         Optional<VpnInterface> optVpnInterface = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, identifier);
 
@@ -1489,7 +1432,10 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
             long label =
                     VpnUtil.getUniqueId(idManager, VpnConstants.VPN_IDPOOL_NAME,
                             VpnUtil.getNextHopLabelKey(rd, prefix));
-
+            if (label == 0) {
+                LOG.error("Unable to fetch label from Id Manager. Bailing out of adding new adjacency {} to vpn interface {} for vpn {}", adj.getIpAddress(), currVpnIntf.getName(), currVpnIntf.getVpnInstanceName());
+                return;
+            }
             List<Adjacency> adjacencies;
             if (optAdjacencies.isPresent()) {
                 adjacencies = optAdjacencies.get().getAdjacency();
@@ -1499,15 +1445,27 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
             }
 
             adjacencies.add(new AdjacencyBuilder(adj).setLabel(label).setNextHopIpList(adj.getNextHopIpList())
-                    .setIpAddress(prefix).setKey(new AdjacencyKey(prefix)).build());
-
+                    .setIpAddress(prefix).setMacAddress(adj.getMacAddress()).setKey(new AdjacencyKey(prefix)).build());
+            
             Adjacencies aug = VpnUtil.getVpnInterfaceAugmentation(adjacencies);
-            VpnInterface newVpnIntf = VpnUtil.getVpnInterface(currVpnIntf.getName(), currVpnIntf.getVpnInstanceName(), aug, dpnId, currVpnIntf.isScheduledForRemove());
+            VpnInterface newVpnIntf = VpnUtil.getVpnInterface(currVpnIntf.getName(), currVpnIntf.getVpnInstanceName(), aug, currVpnIntf.getDpnId(), currVpnIntf.isScheduledForRemove());
 
             VpnUtil.syncUpdate(dataBroker, LogicalDatastoreType.OPERATIONAL, identifier, newVpnIntf);
-            for (String nh : adj.getNextHopIpList()) {
-                addExtraRoute(adj.getIpAddress(), nh, rd, currVpnIntf.getVpnInstanceName(), (int) label,
-                        currVpnIntf.getName());
+            
+            if (adj.getMacAddress() != null && !adj.getMacAddress().isEmpty()) {
+                LOG.trace("Adding prefix {} to interface {} for vpn {}", prefix, currVpnIntf.getName(), currVpnIntf.getVpnInstanceName());
+                VpnUtil.syncUpdate( dataBroker,
+                        LogicalDatastoreType.OPERATIONAL,
+                        VpnUtil.getPrefixToInterfaceIdentifier(
+                                VpnUtil.getVpnId(dataBroker, currVpnIntf.getVpnInstanceName()), prefix),
+                        VpnUtil.getPrefixToInterface(currVpnIntf.getDpnId(), currVpnIntf.getName(), prefix));
+            }
+                      
+            if (adj.getNextHopIpList() != null) {
+                for (String nh : adj.getNextHopIpList()) {
+                    addExtraRoute(adj.getIpAddress(), nh, rd, currVpnIntf.getVpnInstanceName(), (int) label,
+                            currVpnIntf.getName());
+                }
             }
         }
     }
@@ -1540,9 +1498,11 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
 
                             VpnUtil.syncUpdate(dataBroker, LogicalDatastoreType.OPERATIONAL, identifier, newVpnIntf);
 
-                            for (String nh : adj.getNextHopIpList()) {
-                                delExtraRoute(adj.getIpAddress(), nh, rd, currVpnIntf.getVpnInstanceName(),
-                                        currVpnIntf.getName());
+                            if (adj.getNextHopIpList() != null) {
+                                for (String nh : adj.getNextHopIpList()) {
+                                    delExtraRoute(adj.getIpAddress(), nh, rd, currVpnIntf.getVpnInstanceName(),
+                                            currVpnIntf.getName());
+                                }
                             }
                             break;
                         }
@@ -1585,8 +1545,9 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
         // TODO (eperefr): This is a limitation to be stated in docs. When configuring static route to go to
         // another VPN, there can only be one nexthop or, at least, the nexthop to the interVpnLink should be in
         // first place.
-        InterVpnLink interVpnLink = VpnUtil.getInterVpnLinkByEndpointIp(dataBroker, nextHop);
-        if ( interVpnLink != null ) {
+        Optional<InterVpnLink> optInterVpnLink = InterVpnLinkUtil.getInterVpnLinkByEndpointIp(dataBroker, nextHop);
+        if ( optInterVpnLink.isPresent() ) {
+            InterVpnLink interVpnLink = optInterVpnLink.get();
             // If the nexthop is the endpoint of Vpn2, then prefix must be advertised to Vpn1 in DC-GW, with nexthops
             // pointing to the DPNs where Vpn1 is instantiated. LFIB in these DPNS must have a flow entry, with lower
             // priority, where if Label matches then sets the lportTag of the Vpn2 endpoint and goes to LportDispatcher
@@ -1599,7 +1560,11 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
             String dstVpnRd = VpnUtil.getVpnRd(dataBroker, dstVpnUuid);
             long newLabel = VpnUtil.getUniqueId(idManager, VpnConstants.VPN_IDPOOL_NAME,
                     VpnUtil.getNextHopLabelKey(dstVpnRd, destination));
-            VpnUtil.leakRoute(dataBroker, bgpManager, interVpnLink, srcVpnUuid, dstVpnUuid, destination, newLabel);
+            if (newLabel == 0) {
+                LOG.error("Unable to fetch label from Id Manager. Bailing out of adding intervpnlink route for destination {}", destination);
+                return;
+            }
+            InterVpnLinkUtil.leakRoute(dataBroker, bgpManager, interVpnLink, srcVpnUuid, dstVpnUuid, destination, newLabel);
         } else {
             if (rd != null) {
                 addPrefixToBGP(rd, destination, nextHop, label, null);
@@ -1609,7 +1574,7 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
             }
         }
     }
-
     protected void delExtraRoute(String destination, String nextHop, String rd, String routerID, String intfName) {
         if (intfName != null && !intfName.isEmpty()) {
             BigInteger dpnId = InterfaceUtils.getDpnForInterface(ifaceMgrRpcService, intfName);
@@ -1762,61 +1727,6 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
         }
     }
 
-    public void addMIPAdjacency(String vpnName,String vpnInterface, org.opendaylight.yang.gen.v1.urn.ietf.params.xml
-            .ns.yang.ietf.inet.types.rev130715.IpAddress prefix){
-
-        LOG.trace("Adding {} adjacency to VPN Interface {} ",prefix,vpnInterface);
-        InstanceIdentifier<VpnInterface> vpnIfId = VpnUtil.getVpnInterfaceIdentifier(vpnInterface);
-        InstanceIdentifier<Adjacencies> path = vpnIfId.augmentation(Adjacencies.class);
-        Optional<Adjacencies> adjacencies = VpnUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, path);
-        String nextHopIpAddr = null;
-        String nextHopMacAddress = null;
-        String ip = prefix.getIpv4Address().getValue();
-        if (adjacencies.isPresent()) {
-            List<Adjacency> adjacencyList = adjacencies.get().getAdjacency();
-            ip = VpnUtil.getIpPrefix(ip);
-            for (Adjacency adjacs : adjacencyList) {
-                if (adjacs.getMacAddress() != null && !adjacs.getMacAddress().isEmpty()) {
-                    nextHopIpAddr = adjacs.getIpAddress();
-                    nextHopMacAddress = adjacs.getMacAddress();
-                    break;
-                }
-            }
-            if (nextHopMacAddress != null && ip != null) {
-                String rd = VpnUtil.getVpnRd(dataBroker, vpnName);
-                long label =
-                        VpnUtil.getUniqueId(idManager, VpnConstants.VPN_IDPOOL_NAME,
-                                VpnUtil.getNextHopLabelKey((rd != null) ? rd : vpnName, ip));
-                String nextHopIp = nextHopIpAddr.split("/")[0];
-                Adjacency newAdj = new AdjacencyBuilder().setIpAddress(ip).setKey
-                        (new AdjacencyKey(ip)).setNextHopIpList(Arrays.asList(nextHopIp)).build();
-                adjacencyList.add(newAdj);
-                Adjacencies aug = VpnUtil.getVpnInterfaceAugmentation(adjacencyList);
-                VpnInterface newVpnIntf = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(vpnInterface)).
-                        setName(vpnInterface).setVpnInstanceName(vpnName).addAugmentation(Adjacencies.class, aug).build();
-                VpnUtil.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIfId, newVpnIntf);
-                LOG.debug(" Successfully stored subnetroute Adjacency into VpnInterface {}", vpnInterface);
-            }
-        }
-
-    }
-
-    public void removeMIPAdjacency(String vpnName, String vpnInterface, org.opendaylight.yang.gen.v1.urn.ietf.params
-            .xml.ns.yang.ietf.inet.types.rev130715.IpAddress prefix) {
-        String ip = VpnUtil.getIpPrefix(prefix.getIpv4Address().getValue());
-        LOG.trace("Removing {} adjacency from Old VPN Interface {} ",ip,vpnInterface);
-        InstanceIdentifier<VpnInterface> vpnIfId = VpnUtil.getVpnInterfaceIdentifier(vpnInterface);
-        InstanceIdentifier<Adjacencies> path = vpnIfId.augmentation(Adjacencies.class);
-        Optional<Adjacencies> adjacencies = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, path);
-        if (adjacencies.isPresent()) {
-            InstanceIdentifier<Adjacency> adjacencyIdentifier = InstanceIdentifier.builder(VpnInterfaces.class).
-                    child(VpnInterface.class, new VpnInterfaceKey(vpnInterface)).augmentation(Adjacencies.class)
-                    .child(Adjacency.class, new AdjacencyKey(ip)).build();
-            MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, adjacencyIdentifier);
-            LOG.trace("Successfully Deleted Adjacency into VpnInterface {}", vpnInterface);
-        }
-    }
-
     void notifyTaskIfRequired(String intfName) {
         Runnable notifyTask = vpnIntfMap.remove(intfName);
         if (notifyTask == null) {