Fix contains deleting the last Elan-Interface present in CSS
[vpnservice.git] / elanmanager / elanmanager-impl / src / main / java / org / opendaylight / vpnservice / elan / internal / ElanInterfaceManager.java
1 /*
2  * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.vpnservice.elan.internal;
9
10 import com.google.common.base.Optional;
11 import com.google.common.collect.Maps;
12 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
13 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
14 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
15 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
16 import org.opendaylight.vpnservice.elan.utils.ElanConstants;
17 import org.opendaylight.vpnservice.elan.utils.ElanUtils;
18 import org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo;
19 import org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo.InterfaceType;
20 import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
21
22 import org.opendaylight.vpnservice.mdsalutil.NwConstants;
23 import org.opendaylight.vpnservice.itm.globals.ITMConstants;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.Bucket;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.services.info.BoundServices;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
30 import org.opendaylight.vpnservice.mdsalutil.*;
31 import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.ElanDpnInterfaces;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.ElanForwardingTables;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.ElanInterfaces;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan._interface.forwarding.entries.ElanInterfaceMac;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan._interface.forwarding.entries.ElanInterfaceMacBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan._interface.forwarding.entries.ElanInterfaceMacKey;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesList;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfaces;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfacesBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfacesKey;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.forwarding.tables.MacTable;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.forwarding.tables.MacTableKey;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstance;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstanceBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.interfaces.ElanInterface;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.state.Elan;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.state.ElanBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.state.ElanKey;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntry;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntryBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntryKey;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.OdlInterfaceRpcService;
57 import org.opendaylight.yangtools.concepts.ListenerRegistration;
58 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
59 import org.slf4j.Logger;
60 import org.slf4j.LoggerFactory;
61
62 import java.math.BigInteger;
63 import java.util.*;
64 import java.util.concurrent.ConcurrentHashMap;
65 import java.util.concurrent.ConcurrentLinkedQueue;
66
67
68 public class ElanInterfaceManager extends AbstractDataChangeListener<ElanInterface> implements AutoCloseable {
69
70     private static ElanInterfaceManager elanInterfaceManager = new ElanInterfaceManager();
71     private ListenerRegistration<DataChangeListener> elanInterfaceListenerRegistration;
72     private ListenerRegistration<DataChangeListener> itmInterfaceListenerRegistration;
73     private OdlInterfaceRpcService interfaceManagerRpcService;
74     private DataBroker broker;
75     private IMdsalApiManager mdsalManager;
76     private IInterfaceManager interfaceManager;
77     private IdManagerService idManager;
78
79     private ElanForwardingEntriesHandler elanForwardingEntriesHandler;
80     private Map<String, ConcurrentLinkedQueue<ElanInterface>> unProcessedElanInterfaces =
81             new ConcurrentHashMap<String, ConcurrentLinkedQueue<ElanInterface>> ();
82
83     private static final Logger logger = LoggerFactory.getLogger(ElanInterfaceManager.class);
84
85     public ElanInterfaceManager() {
86         super(ElanInterface.class);
87     }
88
89     public static ElanInterfaceManager getElanInterfaceManager() {
90         return elanInterfaceManager;
91     }
92
93     public void setMdSalApiManager(IMdsalApiManager mdsalManager) {
94         this.mdsalManager = mdsalManager;
95     }
96
97     public void setInterfaceManagerRpcService(OdlInterfaceRpcService ifManager) {
98         this.interfaceManagerRpcService = ifManager;
99     }
100
101     public void setElanForwardingEntriesHandler(ElanForwardingEntriesHandler elanForwardingEntriesHandler) {
102         this.elanForwardingEntriesHandler = elanForwardingEntriesHandler;
103     }
104
105     public void setInterfaceManager(IInterfaceManager interfaceManager) {
106         this.interfaceManager = interfaceManager;
107     }
108
109     public void setDataBroker(DataBroker broker) {
110         this.broker = broker;
111     }
112
113     @Override
114     public void close() throws Exception {
115         if (elanInterfaceListenerRegistration != null) {
116             try {
117                 elanInterfaceListenerRegistration.close();
118             } catch (final Exception e) {
119                 logger.error("Error when cleaning up DataChangeListener.", e);
120             }
121             elanInterfaceListenerRegistration = null;
122         }
123     }
124
125     public void registerListener() {
126         try {
127             elanInterfaceListenerRegistration = broker.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
128                     getElanInterfaceWildcardPath(), ElanInterfaceManager.this, DataChangeScope.SUBTREE);
129         } catch (final Exception e) {
130             logger.error("ELAN Interface DataChange listener registration failed !", e);
131             throw new IllegalStateException("ELAN Interface registration Listener failed.", e);
132         }
133     }
134
135     private InstanceIdentifier<?> getElanInterfaceWildcardPath() {
136         return InstanceIdentifier.create(ElanInterfaces.class).child(ElanInterface.class);
137     }
138
139     public void setIdManager(IdManagerService idManager) {
140         this.idManager = idManager;
141     }
142
143     @Override
144     protected void remove(InstanceIdentifier<ElanInterface> identifier, ElanInterface del) {
145         String interfaceName =  del.getName();
146         ElanInstance elanInfo = ElanUtils.getElanInstanceByName(del.getElanInstanceName());
147         removeElanInterface(elanInfo, interfaceName);
148     }
149
150     public void removeElanService(ElanInterface del, InterfaceInfo interfaceInfo) {
151         ElanInstance elanInstance = ElanUtils.getElanInstanceByName(del.getElanInstanceName());
152         String interfaceName = del.getName();
153         removeElanInterface(elanInstance, interfaceInfo);
154         unbindService(elanInstance, interfaceName);
155     }
156
157     public void removeElanInterface(ElanInstance elanInfo, String interfaceName) {
158         String elanName = elanInfo.getElanInstanceName();
159         InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
160         if (interfaceInfo == null) {
161             ElanInterfaceMac elanInterfaceMac =  ElanUtils.getElanInterfaceMacByInterfaceName(interfaceName);
162             if(elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null) {
163                List<MacEntry> macEntries = elanInterfaceMac.getMacEntry();
164                 for(MacEntry macEntry : macEntries) {
165                     ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getMacEntryOperationalDataPath(elanName, macEntry.getMacAddress()));
166                 }
167             }
168             ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName));
169             Elan elanState = ElanUtils.getElanByName(elanName);
170             List<String> elanInterfaces = elanState.getElanInterfaces();
171             elanInterfaces.remove(interfaceName);
172             if(elanInterfaces.isEmpty()) {
173                 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanName));
174                 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanMacTableOperationalDataPath(elanName));
175                 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInfoEntriesOperationalDataPath(elanInfo.getElanTag()));
176             } else {
177                 Elan updateElanState = new ElanBuilder().setElanInterfaces(elanInterfaces).setName(elanName).setKey(new ElanKey(elanName)).build();
178                 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanName), updateElanState);
179             }
180             return;
181         }
182         removeElanInterface(elanInfo, interfaceInfo);
183         unbindService(elanInfo, interfaceName);
184     }
185
186     private void removeElanInterface(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
187
188         BigInteger dpId = interfaceInfo.getDpId();
189         String elanName = elanInfo.getElanInstanceName();
190         long elanTag = elanInfo.getElanTag();
191         String interfaceName = interfaceInfo.getInterfaceName();
192         Elan elanState = ElanUtils.getElanByName(elanName);
193         logger.debug("Removing the Interface:{} from elan:{}", interfaceName, elanName);
194         InstanceIdentifier<ElanInterfaceMac> elanInterfaceId = ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName);
195         Optional<ElanInterfaceMac> existingElanInterface = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanInterfaceId);
196         if(existingElanInterface.isPresent()) {
197             List<MacEntry> existingMacEntries = existingElanInterface.get().getMacEntry();
198             List<MacEntry> macEntries = new ArrayList<>();
199             if (existingMacEntries != null && !existingMacEntries.isEmpty()) {
200                 macEntries.addAll(existingMacEntries);
201             }
202             if(!macEntries.isEmpty()) {
203                 for (MacEntry macEntry : macEntries) {
204                     logger.debug("removing the  mac-entry:{} present on elanInterface:{}", macEntry.getMacAddress().getValue(), interfaceName);
205                     elanForwardingEntriesHandler.deleteElanInterfaceForwardingEntries(elanInfo, interfaceInfo, macEntry);
206                 }
207             }
208         }
209         /*
210          *This condition check is mainly to get DPN-ID in pre-provision deletion scenario after stopping CSS
211          */
212         if(dpId.equals(ElanConstants.INVALID_DPN)) {
213             ElanDpnInterfacesList elanDpnInterfacesList = ElanUtils.getElanDpnInterfacesList(elanName);
214             if(elanDpnInterfacesList != null && !elanDpnInterfacesList.getDpnInterfaces().isEmpty()) {
215                 List<DpnInterfaces> dpnIfList = elanDpnInterfacesList.getDpnInterfaces();
216                 for (DpnInterfaces dpnInterface : dpnIfList) {
217                     DpnInterfaces dpnIfLists = ElanUtils.getElanInterfaceInfoByElanDpn(elanName, dpnInterface.getDpId());
218                     if (dpnIfLists.getInterfaces().contains(interfaceName)) {
219                         logger.debug("deleting the elanInterface from the ElanDpnInterface cache in pre-provision scenario of elan:{} dpn:{} interfaceName:{}", elanName, dpId, interfaceName);
220                         removeElanDpnInterfaceFromOperationalDataStore(elanName, dpId, interfaceName, elanTag);
221                         break;
222                     }
223                 }
224             }
225         } else {
226             removeElanDpnInterfaceFromOperationalDataStore(elanName, dpId, interfaceName, elanTag);
227         }
228
229         removeStaticELanFlows(elanInfo, interfaceInfo);
230         ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, elanInterfaceId);
231         List<String> elanInterfaces = elanState.getElanInterfaces();
232         elanInterfaces.remove(interfaceName);
233
234         if(elanInterfaces.isEmpty()) {
235             ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanName));
236             ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnOperationDataPath(elanName));
237             ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanMacTableOperationalDataPath(elanName));
238             ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInfoEntriesOperationalDataPath(elanInfo.getElanTag()));
239             //ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION, ElanUtils.getElanInstanceConfigurationDataPath(elanName));
240         } else {
241             Elan updateElanState = new ElanBuilder().setElanInterfaces(elanInterfaces).setName(elanName).setKey(new ElanKey(elanName)).build();
242             MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanName), updateElanState);
243         }
244     }
245
246     private void removeElanDpnInterfaceFromOperationalDataStore(String elanName, BigInteger dpId, String interfaceName, long elanTag) {
247         DpnInterfaces dpnInterfaces =  ElanUtils.getElanInterfaceInfoByElanDpn(elanName, dpId);
248         if(dpnInterfaces != null) {
249             List<String> interfaceLists = dpnInterfaces.getInterfaces();
250             interfaceLists.remove(interfaceName);
251             if (interfaceLists == null || interfaceLists.isEmpty()) {
252                 deleteAllRemoteMacsInADpn(elanName, dpId, elanTag);
253                 deleteElanDpnInterface(elanName, dpId);
254             } else {
255                 updateElanDpnInterfacesList(elanName, dpId, interfaceLists);
256             }
257         }
258     }
259
260     private void deleteAllRemoteMacsInADpn(String elanName, BigInteger dpId, long elanTag) {
261         List<DpnInterfaces> dpnInterfaces = ElanUtils.getInvolvedDpnsInElan(elanName);
262         for (DpnInterfaces dpnInterface : dpnInterfaces) {
263             BigInteger currentDpId = dpnInterface.getDpId();
264             if (!currentDpId.equals(dpId)) {
265                 for (String elanInterface : dpnInterface.getInterfaces()) {
266                     ElanInterfaceMac macs = ElanUtils.getElanInterfaceMacByInterfaceName(elanInterface);
267                     if (macs == null) {
268                         continue;
269                     }
270                     for (MacEntry mac : macs.getMacEntry())
271                         mdsalManager.removeFlow(dpId, MDSALUtil.buildFlow(ElanConstants.ELAN_DMAC_TABLE,
272                                 ElanUtils.getKnownDynamicmacFlowRef(ElanConstants.ELAN_DMAC_TABLE, dpId, currentDpId, mac.getMacAddress().getValue(), elanTag)));
273                 }
274             }
275         }
276     }
277
278     @Override
279     protected void update(InstanceIdentifier<ElanInterface> identifier, ElanInterface original, ElanInterface update) {
280         // updating the static-Mac Entries for the existing elanInterface
281         String elanName = update.getElanInstanceName();
282         String interfaceName = update.getName();
283         InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
284         List<PhysAddress> existingPhysAddress = original.getStaticMacEntries();
285         List<PhysAddress> updatedPhysAddress = update.getStaticMacEntries();
286         if(updatedPhysAddress != null && !updatedPhysAddress.isEmpty()) {
287             List<PhysAddress> existingClonedPhyAddress = new ArrayList<>();
288             if(existingPhysAddress != null && !existingPhysAddress.isEmpty()) {
289                 existingClonedPhyAddress.addAll(0, existingPhysAddress);
290                 existingPhysAddress.removeAll(updatedPhysAddress);
291                 updatedPhysAddress.removeAll(existingClonedPhyAddress);
292                 // removing the PhyAddress which are not presented in the updated List
293                 for(PhysAddress physAddress: existingPhysAddress) {
294                     removeInterfaceStaticMacEntires(elanName, interfaceName, physAddress);
295                 }
296             }
297             // Adding the new PhysAddress which are presented in the updated List
298             if(updatedPhysAddress.size() > 0) {
299                 for(PhysAddress physAddress: updatedPhysAddress) {
300                     InstanceIdentifier<MacEntry> macId =  getMacEntryOperationalDataPath(elanName, physAddress);
301                     Optional<MacEntry> existingMacEntry = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, macId);
302                     if(existingMacEntry.isPresent()) {
303                         elanForwardingEntriesHandler.updateElanInterfaceForwardingTablesList(elanName, interfaceName, existingMacEntry.get().getInterface(), existingMacEntry.get());
304                     } else {
305                         elanForwardingEntriesHandler.addElanInterfaceForwardingTableList(ElanUtils.getElanInstanceByName(elanName), interfaceName, physAddress);
306                     }
307                 }
308             }
309         } else if(existingPhysAddress != null && !existingPhysAddress.isEmpty()) {
310             for( PhysAddress physAddress : existingPhysAddress) {
311                 removeInterfaceStaticMacEntires(elanName, interfaceName, physAddress);
312             }
313         }
314     }
315
316     @Override
317     protected void add(InstanceIdentifier<ElanInterface> identifier, ElanInterface elanInterfaceAdded) {
318         String elanInstanceName = elanInterfaceAdded.getElanInstanceName();
319         String interfaceName = elanInterfaceAdded.getName();
320         InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
321         if (interfaceInfo == null) {
322             logger.warn("Interface {} is removed from Interface Oper DS due to port down ", interfaceName);
323             return;
324         }
325         ElanInstance elanInstance = ElanUtils.getElanInstanceByName(elanInstanceName);
326
327         if (elanInstance == null) {
328             elanInstance = new ElanInstanceBuilder().setElanInstanceName(elanInstanceName).setDescription(elanInterfaceAdded.getDescription()).build();
329             //Add the ElanInstance in the Configuration data-store
330             ElanUtils.UpdateOperationalDataStore(broker, idManager, elanInstance);
331             elanInstance = ElanUtils.getElanInstanceByName(elanInstanceName);
332         }
333
334
335         Long elanTag = elanInstance.getElanTag();
336         // If elan tag is not updated, then put the elan interface into unprocessed entry map and entry. Let entries
337         // in this map get processed during ELAN update DCN.
338         if (elanTag == null) {
339             ConcurrentLinkedQueue<ElanInterface> elanInterfaces = unProcessedElanInterfaces.get(elanInstanceName);
340             if (elanInterfaces == null) {
341                 elanInterfaces = new ConcurrentLinkedQueue<ElanInterface>();
342             }
343             elanInterfaces.add(elanInterfaceAdded);
344             unProcessedElanInterfaces.put(elanInstanceName, elanInterfaces);
345             return;
346         }
347         addElanInterface(elanInterfaceAdded, interfaceInfo, elanInstance);
348     }
349
350     void handleunprocessedElanInterfaces(ElanInstance elanInstance) {
351         Queue<ElanInterface> elanInterfaces = unProcessedElanInterfaces.get(elanInstance.getElanInstanceName());
352         if (elanInterfaces == null || elanInterfaces.isEmpty()) {
353             return;
354         }
355         for (ElanInterface elanInterface: elanInterfaces) {
356             String interfaceName = elanInterface.getName();
357             InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
358             addElanInterface(elanInterface, interfaceInfo, elanInstance);
359         }
360     }
361
362     void programRemoteDmacFlow(ElanInstance elanInstance, InterfaceInfo interfaceInfo){
363         ElanDpnInterfacesList elanDpnInterfacesList =  ElanUtils.getElanDpnInterfacesList(elanInstance.getElanInstanceName());
364         List<DpnInterfaces> dpnInterfaceLists =  elanDpnInterfacesList.getDpnInterfaces();
365         for(DpnInterfaces dpnInterfaces : dpnInterfaceLists){
366             if(dpnInterfaces.getDpId().equals(interfaceInfo.getDpId())) {
367                 continue;
368             }
369             List<String> remoteElanInterfaces = dpnInterfaces.getInterfaces();
370             for(String remoteIf : remoteElanInterfaces) {
371                 ElanInterfaceMac elanIfMac = ElanUtils.getElanInterfaceMacByInterfaceName(remoteIf);
372                 InterfaceInfo remoteInterface = interfaceManager.getInterfaceInfo(remoteIf);
373                 if(elanIfMac == null) {
374                     continue;
375                 }
376                 List<MacEntry> remoteMacEntries = elanIfMac.getMacEntry();
377                 if(remoteMacEntries != null) {
378                     for (MacEntry macEntry : remoteMacEntries) {
379                         PhysAddress physAddress = macEntry.getMacAddress();
380                         ElanUtils.setupRemoteDmacFlow(interfaceInfo.getDpId(), remoteInterface.getDpId(),
381                                 remoteInterface.getInterfaceTag(),
382                                 elanInstance.getElanTag(),
383                                 physAddress.getValue(),
384                                 elanInstance.getElanInstanceName());
385                     }
386                 }
387             }
388         }
389     }
390
391     void addElanInterface(ElanInterface elanInterface, InterfaceInfo interfaceInfo, ElanInstance elanInstance) {
392         String interfaceName = elanInterface.getName();
393         String elanInstanceName = elanInterface.getElanInstanceName();
394         List<PhysAddress> staticMacAddresses = elanInterface.getStaticMacEntries();
395         Elan elanInfo = ElanUtils.getElanByName(elanInstanceName);
396         BigInteger dpId = null;
397         if(elanInfo == null) {
398             ElanUtils.UpdateOperationalDataStore(broker, idManager, elanInstance);
399         }
400         if(interfaceInfo != null) {
401             dpId = interfaceInfo.getDpId();
402         }
403         if(dpId != null && !dpId.equals(ElanConstants.INVALID_DPN)) {
404             InstanceIdentifier<DpnInterfaces> elanDpnInterfaces = ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId);
405             Optional<DpnInterfaces> existingElanDpnInterfaces = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanDpnInterfaces);
406             if (!existingElanDpnInterfaces.isPresent()) {
407                 createElanInterfacesList(elanInstanceName, interfaceName, dpId);
408                 /*
409                  * Install remote DMAC flow.
410                  * This is required since this DPN is added later to the elan instance
411                  * and remote DMACs of other interfaces in this elan instance are not present in the current dpn.
412                  */
413                 programRemoteDmacFlow(elanInstance, interfaceInfo);
414             } else {
415                 List<String> elanInterfaces = existingElanDpnInterfaces.get().getInterfaces();
416                 elanInterfaces.add(interfaceName);
417                 updateElanDpnInterfacesList(elanInstanceName, dpId, elanInterfaces);
418             }
419         }
420
421         // add code to install Local/Remote BC group, unknow DMAC entry, terminating service table flow entry
422         // call bindservice of interfacemanager to create ingress table flow enty.
423         //Add interface to the ElanInterfaceForwardingEntires Container
424         createElanInterfaceTablesList(interfaceName);
425         createElanStateList(elanInstanceName, interfaceName);
426         if(interfaceInfo != null) {
427             installFlowsAndGroups(elanInstance, interfaceInfo);
428         }
429         // add the static mac addresses
430         if(staticMacAddresses != null) {
431             for (PhysAddress physAddress : staticMacAddresses) {
432                 InstanceIdentifier<MacEntry> macId = getMacEntryOperationalDataPath(elanInstanceName, physAddress);
433                 Optional<MacEntry> existingMacEntry = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, macId);
434                 if (existingMacEntry.isPresent()) {
435                     elanForwardingEntriesHandler.updateElanInterfaceForwardingTablesList(elanInstanceName, interfaceName, existingMacEntry.get().getInterface(), existingMacEntry.get());
436                 } else {
437                     elanForwardingEntriesHandler.addElanInterfaceForwardingTableList(elanInstance, interfaceName, physAddress);
438                 }
439                 if(isOperational(interfaceInfo)) {
440                     logger.debug("Installing Static Mac-Entry on the Elan Interface:{} with MacAddress:{}", interfaceInfo, physAddress.getValue());
441                     ElanUtils.setupMacFlows(elanInstance, interfaceInfo, ElanConstants.STATIC_MAC_TIMEOUT, physAddress.getValue());
442                 }
443             }
444         }
445     }
446
447     private Map<BigInteger, List<String>> readFePortsDbForElan(String elanName) {
448         ElanDpnInterfacesList elanDpnInterfacesList = ElanUtils.getElanDpnInterfacesList(elanName);
449         HashMap<BigInteger, List<String>> fePortsDb = Maps.newHashMap();
450         if (elanDpnInterfacesList == null) {
451             return fePortsDb;
452         }
453         List<DpnInterfaces> dpnInterfaces = elanDpnInterfacesList.getDpnInterfaces();
454         if (dpnInterfaces == null) {
455             return fePortsDb;
456         }
457         for (DpnInterfaces dpnInterface : dpnInterfaces) {
458             fePortsDb.put(dpnInterface.getDpId(), dpnInterface.getInterfaces());
459         }
460         return fePortsDb;
461     }
462
463     protected void removeInterfaceStaticMacEntires(String elanInstanceName, String interfaceName, PhysAddress physAddress) {
464         InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
465         InstanceIdentifier<MacEntry> macId =  getMacEntryOperationalDataPath(elanInstanceName, physAddress);
466         Optional<MacEntry> existingMacEntry = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, macId);
467
468         if(!existingMacEntry.isPresent()) {
469             return;
470         }
471
472         MacEntry macEntry = new MacEntryBuilder().setMacAddress(physAddress).setInterface(interfaceName).setKey(new MacEntryKey(physAddress)).build();
473         elanForwardingEntriesHandler.deleteElanInterfaceForwardingEntries(ElanUtils.getElanInstanceByName(elanInstanceName), interfaceInfo, macEntry);
474         elanForwardingEntriesHandler.deleteElanInterfaceMacForwardingEntries(interfaceName, physAddress);
475     }
476
477
478     private InstanceIdentifier<MacEntry> getMacEntryOperationalDataPath(String elanName, PhysAddress physAddress) {
479         return InstanceIdentifier.builder(ElanForwardingTables.class).child(MacTable.class,
480                 new MacTableKey(elanName)).child(MacEntry.class, new MacEntryKey(physAddress)).build();
481     }
482
483     public void installFlowsAndGroups(final ElanInstance elanInfo, final InterfaceInfo interfaceInfo) {
484         if (isOperational(interfaceInfo)) {
485
486             // LocalBroadcast Group creation with elan-Interfaces
487             setupElanBroadcastGroups(elanInfo, interfaceInfo);
488
489             setupLocalBroadcastGroups(elanInfo, interfaceInfo);
490             //Terminating Service , UnknownDMAC Table.
491             setupTerminateServiceTable(elanInfo, interfaceInfo);
492             setupUnknownDMacTable(elanInfo, interfaceInfo);
493             setupFilterEqualsTable(elanInfo, interfaceInfo);
494             // bind the Elan service to the Interface
495             bindService(elanInfo, interfaceInfo.getInterfaceName());
496
497             //update the remote-DPNs remoteBC group entry with Tunnels
498             setElanBCGrouponOtherDpns(elanInfo, interfaceInfo);
499         }
500     }
501
502     public void setupFilterEqualsTable(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
503         int ifTag = interfaceInfo.getInterfaceTag();
504         Flow flow = MDSALUtil.buildFlowNew(ElanConstants.ELAN_FILTER_EQUALS_TABLE, getFlowRef(ElanConstants.ELAN_FILTER_EQUALS_TABLE, ifTag),
505                 9, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_FILTER_EQUALS.add(BigInteger.valueOf(ifTag)), getTunnelIdMatchForFilterEqualsLPortTag(ifTag), ElanUtils.getInstructionsInPortForOutGroup(interfaceInfo.getInterfaceName()));
506
507         mdsalManager.installFlow(interfaceInfo.getDpId(), flow);
508
509         Flow flowEntry = MDSALUtil.buildFlowNew(ElanConstants.ELAN_FILTER_EQUALS_TABLE, getFlowRef(ElanConstants.ELAN_FILTER_EQUALS_TABLE, 1000+ifTag),
510                 10, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_FILTER_EQUALS.add(BigInteger.valueOf(ifTag)), getMatchesForFilterEqualsLPortTag(ifTag),
511                 getInstructionsDrop());
512
513         mdsalManager.installFlow(interfaceInfo.getDpId(), flowEntry);
514     }
515
516     public void removeFilterEqualsTable(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
517         int ifTag = interfaceInfo.getInterfaceTag();
518         Flow flow = MDSALUtil.buildFlowNew(ElanConstants.ELAN_FILTER_EQUALS_TABLE, getFlowRef(ElanConstants.ELAN_FILTER_EQUALS_TABLE, ifTag),
519                 9, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_FILTER_EQUALS.add(BigInteger.valueOf(ifTag)), getTunnelIdMatchForFilterEqualsLPortTag(ifTag), ElanUtils.getInstructionsInPortForOutGroup(interfaceInfo.getInterfaceName()));
520
521         mdsalManager.removeFlow(interfaceInfo.getDpId(), flow);
522
523         Flow flowEntity = MDSALUtil.buildFlowNew(ElanConstants.ELAN_FILTER_EQUALS_TABLE, getFlowRef(ElanConstants.ELAN_FILTER_EQUALS_TABLE, 1000+ifTag),
524                 10, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_FILTER_EQUALS.add(BigInteger.valueOf(ifTag)), getMatchesForFilterEqualsLPortTag(ifTag),
525                 getInstructionsDrop());
526
527         mdsalManager.removeFlow(interfaceInfo.getDpId(), flowEntity);
528     }
529
530     private List<Bucket> getRemoteBCGroupBucketInfos(ElanInstance elanInfo,
531                                                      int bucketKeyStart, InterfaceInfo interfaceInfo) {
532         BigInteger dpnId = interfaceInfo.getDpId();
533         int elanTag = elanInfo.getElanTag().intValue();
534         int bucketId = bucketKeyStart;
535         List<Bucket> listBuckets = new ArrayList<Bucket>();
536         ElanDpnInterfacesList elanDpns = ElanUtils.getElanDpnInterfacesList(elanInfo.getElanInstanceName());
537         if(elanDpns != null) {
538             List<DpnInterfaces> dpnInterfaceses = elanDpns.getDpnInterfaces();
539             for(DpnInterfaces dpnInterface : dpnInterfaceses) {
540                if(ElanUtils.isDpnPresent(dpnInterface.getDpId()) && dpnInterface.getDpId() != dpnId && dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty()) {
541                    try {
542                        List<Action> listAction = ElanUtils.getItmEgressAction(dpnId, dpnInterface.getDpId(), (int) elanTag);
543                        listBuckets.add(MDSALUtil.buildBucket(listAction, MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
544                        bucketId++;
545                    } catch (Exception ex) {
546                        logger.error( "Logical Group Interface not found between source Dpn - {}, destination Dpn - {} " ,dpnId, dpnInterface.getDpId() );
547                    }
548                }
549             }
550         }
551         return listBuckets;
552     }
553
554     private List<Bucket> getRemoteBCGroupBuckets(ElanInstance elanInfo,
555                                                          InterfaceInfo interfaceInfo, int bucketId) {
556         BigInteger dpnId = interfaceInfo.getDpId();
557         int elanTag = elanInfo.getElanTag().intValue();
558         List<Bucket> listBucketInfo = new ArrayList<Bucket>();
559         ElanDpnInterfacesList elanDpns = ElanUtils.getElanDpnInterfacesList(elanInfo.getElanInstanceName());
560         if(elanDpns != null) {
561             List<DpnInterfaces> dpnInterfaceses = elanDpns.getDpnInterfaces();
562             for(DpnInterfaces dpnInterface : dpnInterfaceses) {
563                 if(ElanUtils.isDpnPresent(dpnInterface.getDpId()) && dpnInterface.getDpId() != dpnId && dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty()) {
564                     try {
565                         List<Action> listActionInfo = ElanUtils.getItmEgressAction(dpnId, dpnInterface.getDpId(), (int) elanTag);
566                         listBucketInfo.add(MDSALUtil.buildBucket(listActionInfo, 0, bucketId, 0xffffffffL, 0xffffffffL));
567                         bucketId++;
568                     } catch (Exception ex) {
569                         logger.error( "Logical Group Interface not found between source Dpn - {}, destination Dpn - {} " ,dpnId, dpnInterface.getDpId() );
570                     }
571                 }
572             }
573         }
574         return listBucketInfo;
575     }
576
577     private void setElanBCGrouponOtherDpns(ElanInstance elanInfo,
578                                            InterfaceInfo interfaceInfo) {
579         BigInteger dpnId = interfaceInfo.getDpId();
580         int elanTag = elanInfo.getElanTag().intValue();
581         long groupId = ElanUtils.getElanRemoteBCGID(elanTag);
582         List<Bucket> listBucket = new ArrayList<Bucket>();
583         int bucketId = 0;
584         ElanDpnInterfacesList elanDpns = ElanUtils.getElanDpnInterfacesList(elanInfo.getElanInstanceName());
585         if(elanDpns != null) {
586             List<DpnInterfaces> dpnInterfaceses = elanDpns.getDpnInterfaces();
587             for(DpnInterfaces dpnInterface : dpnInterfaceses) {
588               List<Bucket> remoteListBucketInfo = new ArrayList<Bucket>();
589                 if(ElanUtils.isDpnPresent(dpnInterface.getDpId()) && !dpnInterface.getDpId().equals(dpnId) && dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty()) {
590                     for(String ifName : dpnInterface.getInterfaces()) {
591                         // In case if there is a InterfacePort in the cache which is not in
592                         // operational state, skip processing it
593                         InterfaceInfo ifInfo = interfaceManager.getInterfaceInfoFromOperationalDataStore(ifName, interfaceInfo.getInterfaceType());
594                         if (!isOperational(ifInfo)) {
595                             continue;
596                         }
597
598                         listBucket.add(MDSALUtil.buildBucket(getInterfacePortActions(ifInfo), MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
599                         bucketId++;
600                     }
601                     remoteListBucketInfo.addAll(listBucket);
602                     for(DpnInterfaces otherFes : dpnInterfaceses) {
603                         if (ElanUtils.isDpnPresent(otherFes.getDpId()) && otherFes.getDpId() != dpnInterface.getDpId()
604                                 && otherFes.getInterfaces() != null && ! otherFes.getInterfaces().isEmpty()) {
605                             try {
606                                 List<Action> remoteListActionInfo = ElanUtils.getItmEgressAction(dpnInterface.getDpId(), otherFes.getDpId(), (int) elanTag);
607                                 remoteListBucketInfo.add(MDSALUtil.buildBucket(remoteListActionInfo, MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT,MDSALUtil.WATCH_GROUP));
608                                 bucketId++;
609                             } catch (Exception ex) {
610                                 logger.error( "Logical Group Interface not found between source Dpn - {}, destination Dpn - {} " ,dpnInterface.getDpId(), otherFes.getDpId() );
611                                 return;
612                             }
613                         }
614                     }
615                     if(remoteListBucketInfo.size() == 0) {
616                         logger.debug( "No ITM is present on Dpn - {} " ,dpnInterface.getDpId());
617                         continue;
618                     }
619                     Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, MDSALUtil.buildBucketLists(remoteListBucketInfo));
620                     mdsalManager.syncInstallGroup(dpnInterface.getDpId(), group, ElanConstants.DELAY_TIME_IN_MILLISECOND);
621                 }
622             }
623         }
624     }
625
626     private void updateRemoteBCGrouponDpnTunnelEvent(ElanInstance elanInfo,
627                                                InterfaceInfo interfaceInfo, BigInteger dstDpId) {
628         int elanTag = elanInfo.getElanTag().intValue();
629         long groupId = ElanUtils.getElanRemoteBCGID(elanTag);
630         DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanInfo.getElanInstanceName(), interfaceInfo.getDpId());
631         List<DpnInterfaces> elanDpns = ElanUtils.getInvolvedDpnsInElan(elanInfo.getElanInstanceName());
632         if(elanDpns != null) {
633             for(DpnInterfaces dpnInterface : elanDpns) {
634                 int bucketId = 0;
635                 List<Bucket> remoteListBucket = new ArrayList<Bucket>();
636                 if(ElanUtils.isDpnPresent(dstDpId) && dpnInterface.getDpId().equals(dstDpId) && dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty()) {
637                     for(String ifName : dpnInterfaces.getInterfaces()) {
638                         // In case if there is a InterfacePort in the cache which is not in
639                         // operational state, skip processing it
640                         InterfaceInfo ifInfo = interfaceManager.getInterfaceInfoFromOperationalDataStore(ifName, interfaceInfo.getInterfaceType());
641                         if (!isOperational(ifInfo)) {
642                             continue;
643                         }
644
645                         remoteListBucket.add(MDSALUtil.buildBucket(getInterfacePortActions(ifInfo), MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
646                         bucketId++;
647                     }
648                     try {
649                         List<Action> remoteListActionInfo = ElanUtils.getItmEgressAction(interfaceInfo.getDpId(), dstDpId, (int) elanTag);
650                         remoteListBucket.add(MDSALUtil.buildBucket(remoteListActionInfo, MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
651                         bucketId++;
652                     } catch (Exception ex) {
653                         logger.error( "Logical Group Interface not found between source Dpn - {}, destination Dpn - {} " ,dpnInterface.getDpId(), dstDpId);
654                         return;
655                     }
656                     Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, MDSALUtil.buildBucketLists(remoteListBucket));
657                     mdsalManager.syncInstallGroup(interfaceInfo.getDpId(), group, ElanConstants.DELAY_TIME_IN_MILLISECOND);
658                     break;
659                 }
660             }
661         }
662     }
663
664
665     /**
666      * Returns the bucket info with the given interface as the only bucket.
667      */
668     private Bucket getLocalBCGroupBucketInfo(InterfaceInfo interfaceInfo, int bucketIdStart) {
669         return MDSALUtil.buildBucket(getInterfacePortActions(interfaceInfo), MDSALUtil.GROUP_WEIGHT, bucketIdStart, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP);
670     }
671
672     private List<MatchInfo> getMatchesForElanTag(Long elanTag) {
673         List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
674         // Matching metadata
675         mkMatches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
676                 ElanUtils.getElanMetadataLabel(elanTag),
677                 MetaDataUtil.METADATA_MASK_SERVICE }));
678         return mkMatches;
679     }
680
681     private List<Instruction> getInstructionsForOutGroup(
682             long groupId) {
683         List<Instruction> mkInstructions = new ArrayList<Instruction>();
684         List <Action> actions = new ArrayList <Action> ();
685         actions.add(new ActionInfo(ActionType.group, new String[]{Long.toString(groupId)}).buildAction());
686         mkInstructions.add(ElanUtils.getWriteActionInstruction(actions));
687         return mkInstructions;
688     }
689
690     public void removeFlowsAndGroups(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
691         removeStaticELanFlows(elanInfo, interfaceInfo);
692         unbindService(elanInfo, interfaceInfo.getInterfaceName());
693     }
694
695     public void installMacAddressTables(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
696         String interfaceName = interfaceInfo.getInterfaceName();
697         BigInteger currentDpn = interfaceInfo.getDpId();
698         ElanInterfaceMac elanInterfaceMac = ElanUtils.getElanInterfaceMacByInterfaceName(interfaceName);
699         if(elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null) {
700             List<MacEntry> macEntries =  elanInterfaceMac.getMacEntry();
701             for(MacEntry macEntry : macEntries) {
702                 PhysAddress physAddress = macEntry.getMacAddress();
703                 ElanUtils.setupMacFlows(elanInfo, interfaceInfo, macEntry.isIsStaticAddress() ? ElanConstants.STATIC_MAC_TIMEOUT : elanInfo.getMacTimeout(), physAddress.getValue());
704             }
705             //Programming the remoteDMACFlows
706             ElanDpnInterfacesList elanDpnInterfacesList =  ElanUtils.getElanDpnInterfacesList(elanInfo.getElanInstanceName());
707             List<DpnInterfaces> dpnInterfaceLists =  elanDpnInterfacesList.getDpnInterfaces();
708             for(DpnInterfaces dpnInterfaces : dpnInterfaceLists){
709                 if(dpnInterfaces.getDpId().equals(interfaceInfo.getDpId())) {
710                     continue;
711                 }
712                 List<String> remoteElanInterfaces = dpnInterfaces.getInterfaces();
713                 for(String remoteIf : remoteElanInterfaces) {
714                     ElanInterfaceMac elanIfMac = ElanUtils.getElanInterfaceMacByInterfaceName(remoteIf);
715                     InterfaceInfo remoteInterface = interfaceManager.getInterfaceInfo(remoteIf);
716                     if(elanIfMac == null) {
717                         continue;
718                     }
719                     List<MacEntry> remoteMacEntries = elanIfMac.getMacEntry();
720                     if(remoteMacEntries != null) {
721                         for (MacEntry macEntry : remoteMacEntries) {
722                             PhysAddress physAddress = macEntry.getMacAddress();
723                             ElanUtils.setupRemoteDmacFlow(currentDpn, remoteInterface.getDpId(), remoteInterface.getInterfaceTag(), elanInfo.getElanTag(), physAddress.getValue(), elanInfo.getElanInstanceName());
724                         }
725                     }
726                 }
727             }
728         }
729     }
730
731     // Install DMAC entry on dst DPN
732     public void installDMacAddressTables(ElanInstance elanInfo, InterfaceInfo interfaceInfo, BigInteger dstDpId) {
733         String interfaceName = interfaceInfo.getInterfaceName();
734         ElanInterfaceMac elanInterfaceMac = ElanUtils.getElanInterfaceMacByInterfaceName(interfaceName);
735         if(elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null) {
736             List<MacEntry> macEntries =  elanInterfaceMac.getMacEntry();
737             for(MacEntry macEntry : macEntries) {
738                 PhysAddress physAddress = macEntry.getMacAddress();
739                 ElanUtils.setupDMacFlowonRemoteDpn(elanInfo, interfaceInfo, dstDpId, physAddress.getValue());
740             }
741         }
742     }
743
744     public void removeMacAddressTables(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
745         ElanInterfaceMac elanInterfaceMac = ElanUtils.getElanInterfaceMacByInterfaceName(interfaceInfo.getInterfaceName());
746         if(elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null) {
747             List<MacEntry> macEntries =  elanInterfaceMac.getMacEntry();
748             for(MacEntry macEntry : macEntries) {
749                 ElanUtils.deleteMacFlows(elanInfo, interfaceInfo, macEntry);
750             }
751         }
752     }
753
754     public void setupElanBroadcastGroups(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
755         List<Bucket> listBucket = new ArrayList<Bucket>();
756         int bucketId = 0;
757         BigInteger dpnId = interfaceInfo.getDpId();
758         long groupId = ElanUtils.getElanRemoteBCGID(elanInfo.getElanTag());
759
760         DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanInfo.getElanInstanceName(), dpnId);
761         for(String ifName : dpnInterfaces.getInterfaces()) {
762             // In case if there is a InterfacePort in the cache which is not in
763             // operational state, skip processing it
764             InterfaceInfo ifInfo = interfaceManager.getInterfaceInfoFromOperationalDataStore(ifName, interfaceInfo.getInterfaceType());
765             if (!isOperational(ifInfo)) {
766                 continue;
767             }
768
769             listBucket.add(MDSALUtil.buildBucket(getInterfacePortActions(ifInfo), MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
770             bucketId++;
771         }
772         List<Bucket> listBucketInfoRemote = getRemoteBCGroupBuckets(elanInfo, interfaceInfo, bucketId);
773         listBucket.addAll(listBucketInfoRemote);
774
775         Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, MDSALUtil.buildBucketLists(listBucket));
776         logger.trace("installing the localBroadCast Group:{}", group);
777         // In the case of OVS disconnected we receive null object when we query Interface Operation datastore
778         // so the size of the bucket will be zero
779         if(listBucket.size() == 0) {
780             mdsalManager.syncRemoveGroup(dpnId, group);
781         } else {
782             mdsalManager.syncInstallGroup(dpnId, group, ElanConstants.DELAY_TIME_IN_MILLISECOND);
783         }
784     }
785
786     public void setupLocalBroadcastGroups(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
787         List<Bucket> listBucket = new ArrayList<Bucket>();
788         int bucketId = 0;
789         BigInteger dpnId = interfaceInfo.getDpId();
790         long groupId = ElanUtils.getElanLocalBCGID(elanInfo.getElanTag());
791
792         DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanInfo.getElanInstanceName(), dpnId);
793         for(String ifName : dpnInterfaces.getInterfaces()) {
794             // In case if there is a InterfacePort in the cache which is not in
795             // operational state, skip processing it
796             InterfaceInfo ifInfo = interfaceManager.getInterfaceInfoFromOperationalDataStore(ifName, interfaceInfo.getInterfaceType());
797             if (!isOperational(ifInfo)) {
798                 continue;
799             }
800
801             listBucket.add(MDSALUtil.buildBucket(getInterfacePortActions(ifInfo), MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
802             bucketId++;
803         }
804
805
806         Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, MDSALUtil.buildBucketLists(listBucket));
807         logger.trace("installing the localBroadCast Group:{}", group);
808         // In the case of OVS disconnected we receive null object for the Interface Operation datastore
809         // so the size of the bucket will be zero
810         if(listBucket.size() == 0) {
811             mdsalManager.syncRemoveGroup(dpnId, group);
812         } else {
813             mdsalManager.syncInstallGroup(dpnId, group, ElanConstants.DELAY_TIME_IN_MILLISECOND);
814         }
815     }
816
817     public void removeLocalBroadcastGroup(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
818         BigInteger dpnId = interfaceInfo.getDpId();
819         long groupId = ElanUtils.getElanLocalBCGID(elanInfo.getElanTag());
820         List<Bucket> listBuckets = new ArrayList<>();
821         int bucketId = 0;
822         listBuckets.add(getLocalBCGroupBucketInfo(interfaceInfo, bucketId));
823         //listBuckets.addAll(getRemoteBCGroupBucketInfos(elanInfo, 1, interfaceInfo));
824         Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, MDSALUtil.buildBucketLists(listBuckets));
825         logger.trace("deleted the localBroadCast Group:{}", group);
826         mdsalManager.syncRemoveGroup(dpnId, group);
827     }
828
829     public void removeElanBroadcastGroup(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
830         int bucketId = 0;
831         List<Bucket> listBuckets = new ArrayList<>();
832         listBuckets.add(getLocalBCGroupBucketInfo(interfaceInfo, bucketId));
833         bucketId++;
834         listBuckets.addAll(getRemoteBCGroupBucketInfos(elanInfo, bucketId, interfaceInfo));
835         BigInteger dpnId = interfaceInfo.getDpId();
836         long groupId = ElanUtils.getElanRemoteBCGID(elanInfo.getElanTag());
837         Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, MDSALUtil.buildBucketLists(listBuckets));
838         logger.trace("deleting the remoteBroadCast group:{}", group);
839         mdsalManager.syncRemoveGroup(dpnId, group);
840     }
841
842     public void setupTerminateServiceTable(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
843         long elanTag = elanInfo.getElanTag();
844         Flow flowEntity = MDSALUtil.buildFlowNew(NwConstants.INTERNAL_TUNNEL_TABLE, getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE, elanTag),
845                 5, String.format("%s:%d","ITM Flow Entry ",elanTag), 0,  0, ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(elanTag)), ElanUtils.getTunnelMatchesForServiceId((int)elanTag),
846                 getInstructionsForOutGroup(ElanUtils.getElanLocalBCGID(elanTag)));
847
848         mdsalManager.installFlow(interfaceInfo.getDpId(), flowEntity);
849     }
850
851     public void setupUnknownDMacTable(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
852         long elanTag = elanInfo.getElanTag();
853         Flow flowEntity = MDSALUtil.buildFlowNew(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, getFlowRef(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, elanTag),
854                 5, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_UNKNOWN_DMAC.add(BigInteger.valueOf(elanTag)), getMatchesForElanTag(elanTag),
855                 getInstructionsForOutGroup(ElanUtils.getElanRemoteBCGID(elanTag)));
856
857         mdsalManager.installFlow(interfaceInfo.getDpId(), flowEntity);
858     }
859
860     private void removeStaticELanFlows(final ElanInstance elanInfo, final InterfaceInfo interfaceInfo) {
861         BigInteger dpId = interfaceInfo.getDpId();
862         /*
863          * If there are not elan ports, remove the unknown smac and default dmac
864          * flows
865          */
866         DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanInfo.getElanInstanceName(), dpId);
867         if (dpnInterfaces == null || dpnInterfaces.getInterfaces() == null || dpnInterfaces.getInterfaces().isEmpty()) {
868             // No more Elan Interfaces in this DPN
869             logger.debug("deleting the elan: {} present on dpId: {}", elanInfo.getElanInstanceName(), dpId);
870             removeDefaultTermFlow(dpId, elanInfo.getElanTag());
871             removeUnknownDmacFlow(dpId, elanInfo);
872             removeElanBroadcastGroup(elanInfo, interfaceInfo);
873             removeLocalBroadcastGroup(elanInfo, interfaceInfo);
874             removeFilterEqualsTable(elanInfo, interfaceInfo);
875         } else {
876             setupElanBroadcastGroups(elanInfo, interfaceInfo);
877             setupLocalBroadcastGroups(elanInfo, interfaceInfo);
878             removeFilterEqualsTable(elanInfo, interfaceInfo);
879         }
880     }
881
882     private void removeUnknownDmacFlow(BigInteger dpId, ElanInstance elanInfo) {
883         Flow flow = getUnknownDmacFlowEntity(dpId, elanInfo);
884         mdsalManager.removeFlow(dpId, flow);
885     }
886
887     private void removeDefaultTermFlow(BigInteger dpId, long elanTag) {
888         ElanUtils.removeTerminatingServiceAction(dpId, (int) elanTag);
889     }
890
891     private void bindService(ElanInstance elanInfo, String interfaceName) {
892        // interfaceManager.bindService(interfaceName, ElanUtils.getServiceInfo(elanInfo.getElanInstanceName(), elanInfo.getElanTag(), interfaceName));
893
894         int priority = ElanConstants.ELAN_SERVICE_PRIORITY;
895         int instructionKey = 0;
896         List<Instruction> instructions = new ArrayList<Instruction>();
897         instructions.add(MDSALUtil.buildAndGetWriteMetadaInstruction(ElanUtils.getElanMetadataLabel(elanInfo.getElanTag()), MetaDataUtil.METADATA_MASK_SERVICE, ++instructionKey));
898         instructions.add(MDSALUtil.buildAndGetGotoTableInstruction(ElanConstants.ELAN_SMAC_TABLE, ++instructionKey));
899         BoundServices
900                 serviceInfo =
901                 ElanUtils.getBoundServices(String.format("%s.%s.%s", "vpn",elanInfo.getElanInstanceName(), interfaceName),
902                         ElanConstants.ELAN_SERVICE_INDEX, priority,
903                         ElanConstants.COOKIE_ELAN_INGRESS_TABLE, instructions);
904         ElanUtils.syncWrite(broker, LogicalDatastoreType.CONFIGURATION,
905                 ElanUtils.buildServiceId(interfaceName, ElanConstants.ELAN_SERVICE_INDEX), serviceInfo);
906     }
907
908     private void unbindService(ElanInstance elanInfo, String interfaceName) {
909         ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION,
910                 ElanUtils.buildServiceId(interfaceName,ElanConstants.ELAN_SERVICE_INDEX),
911                 ElanUtils.DEFAULT_CALLBACK);
912     }
913
914     private void unbindService(ElanInstance elanInfo, String interfaceName, int vlanId) {
915         ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION,
916                 ElanUtils.buildServiceId(interfaceName,ElanConstants.ELAN_SERVICE_INDEX),
917                 ElanUtils.DEFAULT_CALLBACK);
918     }
919
920     private Flow getUnknownDmacFlowEntity(BigInteger dpId, ElanInstance elanInfo) {
921         long elanTag = elanInfo.getElanTag();
922         List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
923         // Matching metadata
924         mkMatches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
925                 ElanUtils.getElanMetadataLabel(elanTag),
926                 MetaDataUtil.METADATA_MASK_SERVICE }));
927
928         List<Instruction> mkInstructions = new ArrayList<Instruction>();
929         List <Action> actionsInfos = new ArrayList <Action> ();
930         actionsInfos.add(new ActionInfo(ActionType.group, new String[]{Long.toString(ElanUtils.getElanRemoteBCGID(elanTag))}, 0).buildAction());
931         mkInstructions.add(ElanUtils.getWriteActionInstruction(actionsInfos));
932
933         Flow flow = MDSALUtil.buildFlowNew(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, getFlowRef(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, elanTag),
934                 5, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_UNKNOWN_DMAC.add(BigInteger.valueOf(elanTag)),
935                 mkMatches, mkInstructions);
936         return flow;
937     }
938
939     private String getFlowRef(long tableId, long elanTag) {
940         return new StringBuffer().append(tableId).append(elanTag).toString();
941     }
942
943     private List<Action> getInterfacePortActions(InterfaceInfo interfaceInfo) {
944         List<Action> listAction = new ArrayList<Action>();
945         int actionKey = 0;
946         listAction.add((new ActionInfo(ActionType.set_field_tunnel_id, new BigInteger[] {BigInteger.valueOf(interfaceInfo.getInterfaceTag())}, actionKey)).buildAction());
947         actionKey++;
948         listAction.add((new ActionInfo(ActionType.nx_resubmit, new String[] {Short.toString((short)55)}, actionKey)).buildAction());
949         return listAction;
950     }
951
952     private void updateElanDpnInterfacesList(String elanInstanceName, BigInteger dpId, List<String> interfaceNames) {
953         DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId)
954                 .setInterfaces(interfaceNames).setKey(new DpnInterfacesKey(dpId)).build();
955         MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId),
956                 dpnInterface);
957     }
958
959     /**
960      * Delete elan dpn interface from operational DS.
961      *
962      * @param elanInstanceName
963      *            the elan instance name
964      * @param dpId
965      *            the dp id
966      */
967     private void deleteElanDpnInterface(String elanInstanceName, BigInteger dpId) {
968         MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL,
969                 ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId));
970     }
971
972     private List<String> createElanInterfacesList(String elanInstanceName, String interfaceName, BigInteger dpId) {
973         List<String> interfaceNames = new ArrayList<String>();
974         interfaceNames.add(interfaceName);
975         DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId)
976                 .setInterfaces(interfaceNames).setKey(new DpnInterfacesKey(dpId)).build();
977         MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId),
978                 dpnInterface);
979         return interfaceNames;
980     }
981
982     private void createElanInterfaceTablesList(String interfaceName) {
983         InstanceIdentifier<ElanInterfaceMac> elanInterfaceMacTables = ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName);
984         Optional<ElanInterfaceMac> interfaceMacTables = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanInterfaceMacTables);
985         // Adding new Elan Interface Port to the operational DataStore without Static-Mac Entries..
986         if(!interfaceMacTables.isPresent()) {
987             ElanInterfaceMac elanInterfaceMacTable = new ElanInterfaceMacBuilder().setElanInterface(interfaceName).setKey(new ElanInterfaceMacKey(interfaceName)).build();
988             MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName),
989                     elanInterfaceMacTable);
990         }
991     }
992
993     private void createElanStateList(String elanInstanceName, String interfaceName) {
994         InstanceIdentifier<Elan> elanInstance = ElanUtils.getElanInstanceOperationalDataPath(elanInstanceName);
995         Optional<Elan> elanInterfaceLists = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanInstance);
996         // Adding new Elan Interface Port to the operational DataStore without Static-Mac Entries..
997         if(elanInterfaceLists.isPresent()) {
998             List<String> interfaceLists = elanInterfaceLists.get().getElanInterfaces();
999             if(interfaceLists == null) {
1000                 interfaceLists = new ArrayList<>();
1001             }
1002             interfaceLists.add(interfaceName);
1003             Elan elanState = new ElanBuilder().setName(elanInstanceName).setElanInterfaces(interfaceLists).setKey(new ElanKey(elanInstanceName)).build();
1004             MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanInstanceName), elanState);
1005         }
1006     }
1007
1008     private boolean isOperational(InterfaceInfo interfaceInfo) {
1009         if (interfaceInfo == null) {
1010             return false;
1011         }
1012         return ((interfaceInfo.getOpState() == InterfaceInfo.InterfaceOpState.UP) && (interfaceInfo.getAdminState() == InterfaceInfo.InterfaceAdminState.ENABLED));
1013     }
1014
1015     protected void updatedIfPrimaryAttributeChanged(ElanInterface elanInterface, boolean isUpdated) {
1016         String interfaceName = elanInterface.getName();
1017         InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
1018         BigInteger dpId = interfaceInfo.getDpId();
1019         InstanceIdentifier<ElanInterfaceMac> elanInterfaceId = ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName);
1020         Optional<ElanInterfaceMac> existingElanInterface = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanInterfaceId);
1021         ElanInstance elanInfo = ElanUtils.getElanInstanceByName(elanInterface.getElanInstanceName());
1022
1023         if(!existingElanInterface.isPresent()) {
1024             return;
1025         }
1026
1027         List<MacEntry> macEntries = existingElanInterface.get().getMacEntry();
1028         if(macEntries != null && !macEntries.isEmpty()) {
1029             for (MacEntry macEntry : macEntries) {
1030                 if(isUpdated) {
1031                     ElanUtils.setupMacFlows(elanInfo, interfaceInfo, ElanConstants.STATIC_MAC_TIMEOUT, macEntry.getMacAddress().getValue());
1032                 } else {
1033                     ElanUtils.deleteMacFlows(elanInfo, interfaceInfo, macEntry);
1034                 }
1035             }
1036         }
1037
1038         InstanceIdentifier<DpnInterfaces> dpnInterfaceId = ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInterface.getElanInstanceName(), interfaceInfo.getDpId());
1039         Optional<DpnInterfaces> dpnInterfaces =  ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, dpnInterfaceId);
1040         List<String> interfaceLists = dpnInterfaces.get().getInterfaces();
1041
1042         if(isUpdated) {
1043             interfaceLists.add(elanInterface.getName());
1044         } else {
1045             interfaceLists.remove(elanInterface.getName());
1046         }
1047
1048         DpnInterfaces  updateDpnInterfaces = new DpnInterfacesBuilder().setInterfaces(interfaceLists).setDpId(dpId).setKey(new DpnInterfacesKey(dpId)).build();
1049         MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, dpnInterfaceId, updateDpnInterfaces);
1050
1051         if(isUpdated) {
1052             installFlowsAndGroups(elanInfo, interfaceInfo);
1053         } else {
1054             removeStaticELanFlows(elanInfo, interfaceInfo);
1055             unbindService(elanInfo, interfaceName);
1056         }
1057     }
1058
1059     public void handleTunnelStateEvent(BigInteger srcDpId, BigInteger dstDpId) {
1060         ElanDpnInterfaces dpnInterfaceLists =  ElanUtils.getElanDpnInterfacesList();
1061         Set<String> elanInstancesMap = new HashSet<>();
1062         if(dpnInterfaceLists == null) {
1063             return;
1064         }
1065         List<ElanDpnInterfacesList> elanDpnIf = dpnInterfaceLists.getElanDpnInterfacesList();
1066         for(ElanDpnInterfacesList elanDpns: elanDpnIf) {
1067             int cnt = 0;
1068             String elanName = elanDpns.getElanInstanceName();
1069             List<DpnInterfaces> dpnInterfaces = elanDpns.getDpnInterfaces();
1070             if(dpnInterfaces == null) {
1071                continue;
1072             }
1073             for (DpnInterfaces dpnIf : dpnInterfaces) {
1074                if(dpnIf.getDpId().equals(srcDpId) || dpnIf.getDpId().equals(dstDpId)) {
1075                    cnt++;
1076                 }
1077             }
1078             if(cnt == 2) {
1079                 logger.debug("Elan instance:{} is present b/w srcDpn:{} and dstDpn:{}", elanName, srcDpId, dstDpId);
1080                 DpnInterfaces dpnInterface = ElanUtils.getElanInterfaceInfoByElanDpn(elanName, srcDpId);
1081                 Set<String> interfaceLists = new HashSet<>();
1082                 ElanInstance elanInfo = ElanUtils.getElanInstanceByName(elanName);
1083                 interfaceLists.addAll(dpnInterface.getInterfaces());
1084                 for(String ifName : interfaceLists) {
1085                     InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(ifName);
1086                     if (isOperational(interfaceInfo)) {
1087                         if (interfaceInfo.getDpId().equals(srcDpId) && !elanInstancesMap.contains(elanDpns.getElanInstanceName())) {
1088                             elanInstancesMap.add(elanDpns.getElanInstanceName());
1089                             elanInterfaceManager.updateRemoteBCGrouponDpnTunnelEvent(elanInfo, interfaceInfo, dstDpId);
1090                         }
1091                         elanInterfaceManager.installDMacAddressTables(elanInfo, interfaceInfo, dstDpId);
1092                     }
1093                 }
1094             }
1095
1096         }
1097     }
1098
1099     public void handleInterfaceUpated(InterfaceInfo interfaceInfo, ElanInstance elanInstance, boolean isStateUp) {
1100         BigInteger dpId = interfaceInfo.getDpId();
1101         String elanName = elanInstance.getElanInstanceName();
1102         String ifName = interfaceInfo.getInterfaceName();
1103         logger.trace("Handling interface update event for interface with info {} , state {}", interfaceInfo, isStateUp);
1104         if(isStateUp) {
1105
1106             DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanName, dpId);
1107             if(dpnInterfaces == null) {
1108                 createElanInterfacesList(elanName, interfaceInfo.getInterfaceName(), dpId);
1109             } else {
1110               List<String> dpnElanInterfaces = dpnInterfaces.getInterfaces();
1111                 dpnElanInterfaces.add(interfaceInfo.getInterfaceName());
1112                 DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId)
1113                         .setInterfaces(dpnElanInterfaces).setKey(new DpnInterfacesKey(dpId)).build();
1114                 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanName, interfaceInfo.getDpId()), dpnInterface);
1115             }
1116
1117             logger.trace("ElanInterface Service is installed for interface:{}", ifName);
1118             elanInterfaceManager.installFlowsAndGroups(elanInstance, interfaceInfo);
1119             elanInterfaceManager.installMacAddressTables(elanInstance, interfaceInfo);
1120         } else {
1121
1122             DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanName, dpId);
1123             if(dpnInterfaces != null) {
1124                 List<String> dpnElanInterfaces = dpnInterfaces.getInterfaces();
1125                 dpnElanInterfaces.remove(interfaceInfo.getInterfaceName());
1126                 DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId)
1127                         .setInterfaces(dpnElanInterfaces).setKey(new DpnInterfacesKey(dpId)).build();
1128                 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanName, interfaceInfo.getDpId()), dpnInterface);
1129             }
1130             logger.trace("ElanInterface Service is removed for the interface:{}", ifName);
1131             elanInterfaceManager.removeMacAddressTables(elanInstance, interfaceInfo);
1132             elanInterfaceManager.removeFlowsAndGroups(elanInstance, interfaceInfo);
1133         }
1134     }
1135
1136     private List<MatchInfo> getMatchesForFilterEqualsLPortTag(int LportTag) {
1137         List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
1138         // Matching metadata
1139         mkMatches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
1140                 MetaDataUtil.getLportTagMetaData(LportTag),
1141                 MetaDataUtil.METADATA_MASK_LPORT_TAG }));
1142         mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[] {BigInteger.valueOf(LportTag)}));
1143         return mkMatches;
1144     }
1145
1146
1147     private List<MatchInfo> getTunnelIdMatchForFilterEqualsLPortTag(int LportTag) {
1148         List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
1149         // Matching metadata
1150         mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[] {
1151                 BigInteger.valueOf(LportTag)}));
1152         return mkMatches;
1153
1154
1155     }
1156
1157     private List<Instruction> getInstructionsDrop() {
1158         List<Instruction> mkInstructions = new ArrayList<Instruction>();
1159         List <Action> actionsInfos = new ArrayList <Action> ();
1160         actionsInfos.add(new ActionInfo(ActionType.drop_action, new String[]{}).buildAction());
1161         mkInstructions.add(ElanUtils.getWriteActionInstruction(actionsInfos));
1162         return mkInstructions;
1163     }
1164
1165 }