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