2 * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
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
8 package org.opendaylight.vpnservice.elan.internal;
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;
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;
62 import java.math.BigInteger;
64 import java.util.concurrent.ConcurrentHashMap;
65 import java.util.concurrent.ConcurrentLinkedQueue;
68 public class ElanInterfaceManager extends AbstractDataChangeListener<ElanInterface> implements AutoCloseable {
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;
79 private ElanForwardingEntriesHandler elanForwardingEntriesHandler;
80 private Map<String, ConcurrentLinkedQueue<ElanInterface>> unProcessedElanInterfaces =
81 new ConcurrentHashMap<String, ConcurrentLinkedQueue<ElanInterface>> ();
83 private static final Logger logger = LoggerFactory.getLogger(ElanInterfaceManager.class);
85 public ElanInterfaceManager() {
86 super(ElanInterface.class);
89 public static ElanInterfaceManager getElanInterfaceManager() {
90 return elanInterfaceManager;
93 public void setMdSalApiManager(IMdsalApiManager mdsalManager) {
94 this.mdsalManager = mdsalManager;
97 public void setInterfaceManagerRpcService(OdlInterfaceRpcService ifManager) {
98 this.interfaceManagerRpcService = ifManager;
101 public void setElanForwardingEntriesHandler(ElanForwardingEntriesHandler elanForwardingEntriesHandler) {
102 this.elanForwardingEntriesHandler = elanForwardingEntriesHandler;
105 public void setInterfaceManager(IInterfaceManager interfaceManager) {
106 this.interfaceManager = interfaceManager;
109 public void setDataBroker(DataBroker broker) {
110 this.broker = broker;
114 public void close() throws Exception {
115 if (elanInterfaceListenerRegistration != null) {
117 elanInterfaceListenerRegistration.close();
118 } catch (final Exception e) {
119 logger.error("Error when cleaning up DataChangeListener.", e);
121 elanInterfaceListenerRegistration = null;
125 public void registerListener() {
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);
135 private InstanceIdentifier<?> getElanInterfaceWildcardPath() {
136 return InstanceIdentifier.create(ElanInterfaces.class).child(ElanInterface.class);
139 public void setIdManager(IdManagerService idManager) {
140 this.idManager = idManager;
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);
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);
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()));
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()));
177 Elan updateElanState = new ElanBuilder().setElanInterfaces(elanInterfaces).setName(elanName).setKey(new ElanKey(elanName)).build();
178 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanName), updateElanState);
182 removeElanInterface(elanInfo, interfaceInfo);
183 unbindService(elanInfo, interfaceName);
186 private void removeElanInterface(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
188 BigInteger dpId = interfaceInfo.getDpId();
189 String elanName = elanInfo.getElanInstanceName();
190 String interfaceName = interfaceInfo.getInterfaceName();
191 Elan elanState = ElanUtils.getElanByName(elanName);
192 logger.debug("Removing the Interface:{} from elan:{}", interfaceName, elanName);
193 InstanceIdentifier<ElanInterfaceMac> elanInterfaceId = ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName);
194 Optional<ElanInterfaceMac> existingElanInterface = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanInterfaceId);
195 if(existingElanInterface.isPresent()) {
196 List<MacEntry> macEntries = existingElanInterface.get().getMacEntry();
197 if(macEntries != null && !macEntries.isEmpty()) {
198 for (MacEntry macEntry : macEntries) {
199 logger.debug("removing the mac-entry:{} present on elanInterface:{}", macEntry.getMacAddress().getValue(), interfaceName);
200 elanForwardingEntriesHandler.deleteElanInterfaceForwardingEntries(elanInfo, interfaceInfo, macEntry);
205 *This condition check is mainly to get DPN-ID in pre-provision deletion scenario after stopping CSS
207 if(dpId.equals(ElanConstants.INVALID_DPN)) {
208 ElanDpnInterfacesList elanDpnInterfacesList = ElanUtils.getElanDpnInterfacesList(elanName);
209 if(elanDpnInterfacesList != null && !elanDpnInterfacesList.getDpnInterfaces().isEmpty()) {
210 List<DpnInterfaces> dpnIfList = elanDpnInterfacesList.getDpnInterfaces();
211 for (DpnInterfaces dpnInterface : dpnIfList) {
212 DpnInterfaces dpnIfLists = ElanUtils.getElanInterfaceInfoByElanDpn(elanName, dpnInterface.getDpId());
213 if (dpnIfLists.getInterfaces().contains(interfaceName)) {
214 logger.debug("deleting the elanInterface from the ElanDpnInterface cache in pre-provision scenario of elan:{} dpn:{} interfaceName:{}", elanName, dpId, interfaceName);
215 removeElanDpnInterfaceFromOperationalDataStore(elanName, dpId, interfaceName);
221 removeElanDpnInterfaceFromOperationalDataStore(elanName, dpId, interfaceName);
224 removeStaticELanFlows(elanInfo, interfaceInfo);
225 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, elanInterfaceId);
226 List<String> elanInterfaces = elanState.getElanInterfaces();
227 elanInterfaces.remove(interfaceName);
229 if(elanInterfaces.isEmpty()) {
230 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanName));
231 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnOperationDataPath(elanName));
232 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanMacTableOperationalDataPath(elanName));
233 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInfoEntriesOperationalDataPath(elanInfo.getElanTag()));
234 //ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION, ElanUtils.getElanInstanceConfigurationDataPath(elanName));
236 Elan updateElanState = new ElanBuilder().setElanInterfaces(elanInterfaces).setName(elanName).setKey(new ElanKey(elanName)).build();
237 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanName), updateElanState);
241 private void removeElanDpnInterfaceFromOperationalDataStore(String elanName, BigInteger dpId, String interfaceName) {
242 DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanName, dpId);
243 if(dpnInterfaces != null) {
244 List<String> interfaceLists = dpnInterfaces.getInterfaces();
245 interfaceLists.remove(interfaceName);
246 updateElanDpnInterfacesList(elanName, dpId, interfaceLists);
251 protected void update(InstanceIdentifier<ElanInterface> identifier, ElanInterface original, ElanInterface update) {
252 // updating the static-Mac Entries for the existing elanInterface
253 String elanName = update.getElanInstanceName();
254 String interfaceName = update.getName();
255 InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
256 List<PhysAddress> existingPhysAddress = original.getStaticMacEntries();
257 List<PhysAddress> updatedPhysAddress = update.getStaticMacEntries();
258 if(updatedPhysAddress != null && !updatedPhysAddress.isEmpty()) {
259 List<PhysAddress> existingClonedPhyAddress = new ArrayList<>();
260 if(existingPhysAddress != null && !existingPhysAddress.isEmpty()) {
261 existingClonedPhyAddress.addAll(0, existingPhysAddress);
262 existingPhysAddress.removeAll(updatedPhysAddress);
263 updatedPhysAddress.removeAll(existingClonedPhyAddress);
264 // removing the PhyAddress which are not presented in the updated List
265 for(PhysAddress physAddress: existingPhysAddress) {
266 removeInterfaceStaticMacEntires(elanName, interfaceName, physAddress);
269 // Adding the new PhysAddress which are presented in the updated List
270 if(updatedPhysAddress.size() > 0) {
271 for(PhysAddress physAddress: updatedPhysAddress) {
272 InstanceIdentifier<MacEntry> macId = getMacEntryOperationalDataPath(elanName, physAddress);
273 Optional<MacEntry> existingMacEntry = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, macId);
274 if(existingMacEntry.isPresent()) {
275 elanForwardingEntriesHandler.updateElanInterfaceForwardingTablesList(elanName, interfaceName, existingMacEntry.get().getInterface(), existingMacEntry.get());
277 elanForwardingEntriesHandler.addElanInterfaceForwardingTableList(ElanUtils.getElanInstanceByName(elanName), interfaceName, physAddress);
281 } else if(existingPhysAddress != null && !existingPhysAddress.isEmpty()) {
282 for( PhysAddress physAddress : existingPhysAddress) {
283 removeInterfaceStaticMacEntires(elanName, interfaceName, physAddress);
289 protected void add(InstanceIdentifier<ElanInterface> identifier, ElanInterface elanInterfaceAdded) {
290 String elanInstanceName = elanInterfaceAdded.getElanInstanceName();
291 String interfaceName = elanInterfaceAdded.getName();
292 InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
293 ElanInstance elanInstance = ElanUtils.getElanInstanceByName(elanInstanceName);
295 if (elanInstance == null) {
296 elanInstance = new ElanInstanceBuilder().setElanInstanceName(elanInstanceName).setDescription(elanInterfaceAdded.getDescription()).build();
297 //Add the ElanInstance in the Configuration data-store
298 ElanUtils.UpdateOperationalDataStore(broker, idManager, elanInstance);
299 elanInstance = ElanUtils.getElanInstanceByName(elanInstanceName);
303 Long elanTag = elanInstance.getElanTag();
304 // If elan tag is not updated, then put the elan interface into unprocessed entry map and entry. Let entries
305 // in this map get processed during ELAN update DCN.
306 if (elanTag == null) {
307 ConcurrentLinkedQueue<ElanInterface> elanInterfaces = unProcessedElanInterfaces.get(elanInstanceName);
308 if (elanInterfaces == null) {
309 elanInterfaces = new ConcurrentLinkedQueue<ElanInterface>();
311 elanInterfaces.add(elanInterfaceAdded);
312 unProcessedElanInterfaces.put(elanInstanceName, elanInterfaces);
315 addElanInterface(elanInterfaceAdded, interfaceInfo, elanInstance);
318 void handleunprocessedElanInterfaces(ElanInstance elanInstance) {
319 Queue<ElanInterface> elanInterfaces = unProcessedElanInterfaces.get(elanInstance.getElanInstanceName());
320 if (elanInterfaces == null || elanInterfaces.isEmpty()) {
323 for (ElanInterface elanInterface: elanInterfaces) {
324 String interfaceName = elanInterface.getName();
325 InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
326 addElanInterface(elanInterface, interfaceInfo, elanInstance);
330 void addElanInterface(ElanInterface elanInterface, InterfaceInfo interfaceInfo, ElanInstance elanInstance) {
331 String interfaceName = elanInterface.getName();
332 String elanInstanceName = elanInterface.getElanInstanceName();
333 List<PhysAddress> staticMacAddresses = elanInterface.getStaticMacEntries();
334 Elan elanInfo = ElanUtils.getElanByName(elanInstanceName);
335 BigInteger dpId = null;
336 if(elanInfo == null) {
337 ElanUtils.UpdateOperationalDataStore(broker, idManager, elanInstance);
339 if(interfaceInfo != null) {
340 dpId = interfaceInfo.getDpId();
342 if(dpId != null && !dpId.equals(ElanConstants.INVALID_DPN)) {
343 InstanceIdentifier<DpnInterfaces> elanDpnInterfaces = ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId);
344 Optional<DpnInterfaces> existingElanDpnInterfaces = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanDpnInterfaces);
345 if (!existingElanDpnInterfaces.isPresent()) {
346 createElanInterfacesList(elanInstanceName, interfaceName, dpId);
348 List<String> elanInterfaces = existingElanDpnInterfaces.get().getInterfaces();
349 elanInterfaces.add(interfaceName);
350 updateElanDpnInterfacesList(elanInstanceName, dpId, elanInterfaces);
354 // add code to install Local/Remote BC group, unknow DMAC entry, terminating service table flow entry
355 // call bindservice of interfacemanager to create ingress table flow enty.
356 //Add interface to the ElanInterfaceForwardingEntires Container
357 createElanInterfaceTablesList(interfaceName);
358 createElanStateList(elanInstanceName, interfaceName);
359 if(interfaceInfo != null) {
360 installFlowsAndGroups(elanInstance, interfaceInfo);
362 // add the static mac addresses
363 if(staticMacAddresses != null) {
364 for (PhysAddress physAddress : staticMacAddresses) {
365 InstanceIdentifier<MacEntry> macId = getMacEntryOperationalDataPath(elanInstanceName, physAddress);
366 Optional<MacEntry> existingMacEntry = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, macId);
367 if (existingMacEntry.isPresent()) {
368 elanForwardingEntriesHandler.updateElanInterfaceForwardingTablesList(elanInstanceName, interfaceName, existingMacEntry.get().getInterface(), existingMacEntry.get());
370 elanForwardingEntriesHandler.addElanInterfaceForwardingTableList(elanInstance, interfaceName, physAddress);
372 if(interfaceInfo != null && isOperational(interfaceInfo)) {
373 logger.debug("Installing Static Mac-Entry on the Elan Interface:{} with MacAddress:{}", interfaceInfo, physAddress.getValue());
374 ElanUtils.setupMacFlows(elanInstance, interfaceInfo, ElanConstants.STATIC_MAC_TIMEOUT, physAddress.getValue());
380 private Map<BigInteger, List<String>> readFePortsDbForElan(String elanName) {
381 ElanDpnInterfacesList elanDpnInterfacesList = ElanUtils.getElanDpnInterfacesList(elanName);
382 HashMap<BigInteger, List<String>> fePortsDb = Maps.newHashMap();
383 if (elanDpnInterfacesList == null) {
386 List<DpnInterfaces> dpnInterfaces = elanDpnInterfacesList.getDpnInterfaces();
387 if (dpnInterfaces == null) {
390 for (DpnInterfaces dpnInterface : dpnInterfaces) {
391 fePortsDb.put(dpnInterface.getDpId(), dpnInterface.getInterfaces());
396 protected void removeInterfaceStaticMacEntires(String elanInstanceName, String interfaceName, PhysAddress physAddress) {
397 InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
398 InstanceIdentifier<MacEntry> macId = getMacEntryOperationalDataPath(elanInstanceName, physAddress);
399 Optional<MacEntry> existingMacEntry = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, macId);
401 if(!existingMacEntry.isPresent()) {
405 MacEntry macEntry = new MacEntryBuilder().setMacAddress(physAddress).setInterface(interfaceName).setKey(new MacEntryKey(physAddress)).build();
406 elanForwardingEntriesHandler.deleteElanInterfaceForwardingEntries(ElanUtils.getElanInstanceByName(elanInstanceName), interfaceInfo, macEntry);
407 elanForwardingEntriesHandler.deleteElanInterfaceMacForwardingEntries(interfaceName, physAddress);
411 private InstanceIdentifier<MacEntry> getMacEntryOperationalDataPath(String elanName, PhysAddress physAddress) {
412 return InstanceIdentifier.builder(ElanForwardingTables.class).child(MacTable.class,
413 new MacTableKey(elanName)).child(MacEntry.class, new MacEntryKey(physAddress)).build();
416 public void installFlowsAndGroups(final ElanInstance elanInfo, final InterfaceInfo interfaceInfo) {
417 if (isOperational(interfaceInfo)) {
419 // LocalBroadcast Group creation with elan-Interfaces
420 setupElanBroadcastGroups(elanInfo, interfaceInfo);
422 setupLocalBroadcastGroups(elanInfo, interfaceInfo);
423 //Terminating Service , UnknownDMAC Table.
424 setupTerminateServiceTable(elanInfo, interfaceInfo);
425 setupUnknownDMacTable(elanInfo, interfaceInfo);
426 setupFilterEqualsTable(elanInfo, interfaceInfo);
427 // bind the Elan service to the Interface
428 bindService(elanInfo, interfaceInfo.getInterfaceName());
430 //update the remote-DPNs remoteBC group entry with Tunnels
431 setElanBCGrouponOtherDpns(elanInfo, interfaceInfo);
435 public void setupFilterEqualsTable(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
436 int ifTag = interfaceInfo.getInterfaceTag();
437 Flow flow = MDSALUtil.buildFlowNew(ElanConstants.ELAN_FILTER_EQUALS_TABLE, getFlowRef(ElanConstants.ELAN_FILTER_EQUALS_TABLE, ifTag),
438 9, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_FILTER_EQUALS.add(BigInteger.valueOf(ifTag)), getTunnelIdMatchForFilterEqualsLPortTag(ifTag), ElanUtils.getInstructionsInPortForOutGroup(interfaceInfo.getInterfaceName()));
440 mdsalManager.installFlow(interfaceInfo.getDpId(), flow);
442 Flow flowEntry = MDSALUtil.buildFlowNew(ElanConstants.ELAN_FILTER_EQUALS_TABLE, getFlowRef(ElanConstants.ELAN_FILTER_EQUALS_TABLE, 1000+ifTag),
443 10, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_FILTER_EQUALS.add(BigInteger.valueOf(ifTag)), getMatchesForFilterEqualsLPortTag(ifTag),
444 getInstructionsDrop());
446 mdsalManager.installFlow(interfaceInfo.getDpId(), flowEntry);
449 public void removeFilterEqualsTable(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
450 int ifTag = interfaceInfo.getInterfaceTag();
451 Flow flow = MDSALUtil.buildFlowNew(ElanConstants.ELAN_FILTER_EQUALS_TABLE, getFlowRef(ElanConstants.ELAN_FILTER_EQUALS_TABLE, ifTag),
452 9, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_FILTER_EQUALS.add(BigInteger.valueOf(ifTag)), getTunnelIdMatchForFilterEqualsLPortTag(ifTag), ElanUtils.getInstructionsInPortForOutGroup(interfaceInfo.getInterfaceName()));
454 mdsalManager.removeFlow(interfaceInfo.getDpId(), flow);
456 Flow flowEntity = MDSALUtil.buildFlowNew(ElanConstants.ELAN_FILTER_EQUALS_TABLE, getFlowRef(ElanConstants.ELAN_FILTER_EQUALS_TABLE, 1000+ifTag),
457 10, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_FILTER_EQUALS.add(BigInteger.valueOf(ifTag)), getMatchesForFilterEqualsLPortTag(ifTag),
458 getInstructionsDrop());
460 mdsalManager.removeFlow(interfaceInfo.getDpId(), flowEntity);
463 private List<Bucket> getRemoteBCGroupBucketInfos(ElanInstance elanInfo,
464 int bucketKeyStart, InterfaceInfo interfaceInfo) {
465 BigInteger dpnId = interfaceInfo.getDpId();
466 int elanTag = elanInfo.getElanTag().intValue();
467 int bucketId = bucketKeyStart;
468 List<Bucket> listBuckets = new ArrayList<Bucket>();
469 ElanDpnInterfacesList elanDpns = ElanUtils.getElanDpnInterfacesList(elanInfo.getElanInstanceName());
470 if(elanDpns != null) {
471 List<DpnInterfaces> dpnInterfaceses = elanDpns.getDpnInterfaces();
472 for(DpnInterfaces dpnInterface : dpnInterfaceses) {
473 if(ElanUtils.isDpnPresent(dpnInterface.getDpId()) && dpnInterface.getDpId() != dpnId && dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty()) {
475 List<Action> listAction = ElanUtils.getItmEgressAction(dpnId, dpnInterface.getDpId(), (int) elanTag);
476 listBuckets.add(MDSALUtil.buildBucket(listAction, MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
478 } catch (Exception ex) {
479 logger.error( "Logical Group Interface not found between source Dpn - {}, destination Dpn - {} " ,dpnId, dpnInterface.getDpId() );
487 private List<Bucket> getRemoteBCGroupBuckets(ElanInstance elanInfo,
488 InterfaceInfo interfaceInfo, int bucketId) {
489 BigInteger dpnId = interfaceInfo.getDpId();
490 int elanTag = elanInfo.getElanTag().intValue();
491 List<Bucket> listBucketInfo = new ArrayList<Bucket>();
492 ElanDpnInterfacesList elanDpns = ElanUtils.getElanDpnInterfacesList(elanInfo.getElanInstanceName());
493 if(elanDpns != null) {
494 List<DpnInterfaces> dpnInterfaceses = elanDpns.getDpnInterfaces();
495 for(DpnInterfaces dpnInterface : dpnInterfaceses) {
496 if(ElanUtils.isDpnPresent(dpnInterface.getDpId()) && dpnInterface.getDpId() != dpnId && dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty()) {
498 List<Action> listActionInfo = ElanUtils.getItmEgressAction(dpnId, dpnInterface.getDpId(), (int) elanTag);
499 listBucketInfo.add(MDSALUtil.buildBucket(listActionInfo, 0, bucketId, 0xffffffffL, 0xffffffffL));
501 } catch (Exception ex) {
502 logger.error( "Logical Group Interface not found between source Dpn - {}, destination Dpn - {} " ,dpnId, dpnInterface.getDpId() );
507 return listBucketInfo;
510 private void setElanBCGrouponOtherDpns(ElanInstance elanInfo,
511 InterfaceInfo interfaceInfo) {
512 BigInteger dpnId = interfaceInfo.getDpId();
513 int elanTag = elanInfo.getElanTag().intValue();
514 long groupId = ElanUtils.getElanRemoteBCGID(elanTag);
515 List<Bucket> listBucket = new ArrayList<Bucket>();
517 ElanDpnInterfacesList elanDpns = ElanUtils.getElanDpnInterfacesList(elanInfo.getElanInstanceName());
518 if(elanDpns != null) {
519 List<DpnInterfaces> dpnInterfaceses = elanDpns.getDpnInterfaces();
520 for(DpnInterfaces dpnInterface : dpnInterfaceses) {
521 List<Bucket> remoteListBucketInfo = new ArrayList<Bucket>();
522 if(ElanUtils.isDpnPresent(dpnInterface.getDpId()) && !dpnInterface.getDpId().equals(dpnId) && dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty()) {
523 for(String ifName : dpnInterface.getInterfaces()) {
524 // In case if there is a InterfacePort in the cache which is not in
525 // operational state, skip processing it
526 InterfaceInfo ifInfo = interfaceManager.getInterfaceInfoFromOperationalDataStore(ifName, interfaceInfo.getInterfaceType());
527 if (!isOperational(ifInfo)) {
531 listBucket.add(MDSALUtil.buildBucket(getInterfacePortActions(ifInfo), MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
534 remoteListBucketInfo.addAll(listBucket);
535 for(DpnInterfaces otherFes : dpnInterfaceses) {
536 if (ElanUtils.isDpnPresent(otherFes.getDpId()) && otherFes.getDpId() != dpnInterface.getDpId()
537 && otherFes.getInterfaces() != null && ! otherFes.getInterfaces().isEmpty()) {
539 List<Action> remoteListActionInfo = ElanUtils.getItmEgressAction(dpnInterface.getDpId(), otherFes.getDpId(), (int) elanTag);
540 remoteListBucketInfo.add(MDSALUtil.buildBucket(remoteListActionInfo, MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT,MDSALUtil.WATCH_GROUP));
542 } catch (Exception ex) {
543 logger.error( "Logical Group Interface not found between source Dpn - {}, destination Dpn - {} " ,dpnInterface.getDpId(), otherFes.getDpId() );
548 if(remoteListBucketInfo.size() == 0) {
549 logger.debug( "No ITM is present on Dpn - {} " ,dpnInterface.getDpId());
552 Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, MDSALUtil.buildBucketLists(remoteListBucketInfo));
553 mdsalManager.syncInstallGroup(dpnInterface.getDpId(), group, ElanConstants.DELAY_TIME_IN_MILLISECOND);
559 private void updateRemoteBCGrouponDpnTunnelEvent(ElanInstance elanInfo,
560 InterfaceInfo interfaceInfo, BigInteger dstDpId) {
561 int elanTag = elanInfo.getElanTag().intValue();
562 long groupId = ElanUtils.getElanRemoteBCGID(elanTag);
563 DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanInfo.getElanInstanceName(), interfaceInfo.getDpId());
564 List<DpnInterfaces> elanDpns = ElanUtils.getInvolvedDpnsInElan(elanInfo.getElanInstanceName());
565 if(elanDpns != null) {
566 for(DpnInterfaces dpnInterface : elanDpns) {
568 List<Bucket> remoteListBucket = new ArrayList<Bucket>();
569 if(ElanUtils.isDpnPresent(dstDpId) && dpnInterface.getDpId().equals(dstDpId) && dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty()) {
570 for(String ifName : dpnInterfaces.getInterfaces()) {
571 // In case if there is a InterfacePort in the cache which is not in
572 // operational state, skip processing it
573 InterfaceInfo ifInfo = interfaceManager.getInterfaceInfoFromOperationalDataStore(ifName, interfaceInfo.getInterfaceType());
574 if (!isOperational(ifInfo)) {
578 remoteListBucket.add(MDSALUtil.buildBucket(getInterfacePortActions(ifInfo), MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
582 List<Action> remoteListActionInfo = ElanUtils.getItmEgressAction(interfaceInfo.getDpId(), dstDpId, (int) elanTag);
583 remoteListBucket.add(MDSALUtil.buildBucket(remoteListActionInfo, MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
585 } catch (Exception ex) {
586 logger.error( "Logical Group Interface not found between source Dpn - {}, destination Dpn - {} " ,dpnInterface.getDpId(), dstDpId);
589 Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, MDSALUtil.buildBucketLists(remoteListBucket));
590 mdsalManager.syncInstallGroup(interfaceInfo.getDpId(), group, ElanConstants.DELAY_TIME_IN_MILLISECOND);
599 * Returns the bucket info with the given interface as the only bucket.
601 private Bucket getLocalBCGroupBucketInfo(InterfaceInfo interfaceInfo, int bucketIdStart) {
602 return MDSALUtil.buildBucket(getInterfacePortActions(interfaceInfo), MDSALUtil.GROUP_WEIGHT, bucketIdStart, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP);
605 private List<MatchInfo> getMatchesForElanTag(Long elanTag) {
606 List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
608 mkMatches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
609 ElanUtils.getElanMetadataLabel(elanTag),
610 MetaDataUtil.METADATA_MASK_SERVICE }));
614 private List<Instruction> getInstructionsForOutGroup(
616 List<Instruction> mkInstructions = new ArrayList<Instruction>();
617 List <Action> actions = new ArrayList <Action> ();
618 actions.add(new ActionInfo(ActionType.group, new String[]{Long.toString(groupId)}).buildAction());
619 mkInstructions.add(ElanUtils.getWriteActionInstruction(actions));
620 return mkInstructions;
623 public void removeFlowsAndGroups(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
624 removeStaticELanFlows(elanInfo, interfaceInfo);
625 unbindService(elanInfo, interfaceInfo.getInterfaceName());
628 public void installMacAddressTables(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
629 String interfaceName = interfaceInfo.getInterfaceName();
630 BigInteger currentDpn = interfaceInfo.getDpId();
631 ElanInterfaceMac elanInterfaceMac = ElanUtils.getElanInterfaceMacByInterfaceName(interfaceName);
632 if(elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null) {
633 List<MacEntry> macEntries = elanInterfaceMac.getMacEntry();
634 for(MacEntry macEntry : macEntries) {
635 PhysAddress physAddress = macEntry.getMacAddress();
636 ElanUtils.setupMacFlows(elanInfo, interfaceInfo, macEntry.isIsStaticAddress() ? ElanConstants.STATIC_MAC_TIMEOUT : elanInfo.getMacTimeout(), physAddress.getValue());
638 //Programming the remoteDMACFlows
639 ElanDpnInterfacesList elanDpnInterfacesList = ElanUtils.getElanDpnInterfacesList(elanInfo.getElanInstanceName());
640 List<DpnInterfaces> dpnInterfaceLists = elanDpnInterfacesList.getDpnInterfaces();
641 for(DpnInterfaces dpnInterfaces : dpnInterfaceLists){
642 if(dpnInterfaces.getDpId().equals(interfaceInfo.getDpId())) {
645 List<String> remoteElanInterfaces = dpnInterfaces.getInterfaces();
646 for(String remoteIf : remoteElanInterfaces) {
647 ElanInterfaceMac elanIfMac = ElanUtils.getElanInterfaceMacByInterfaceName(remoteIf);
648 InterfaceInfo remoteInterface = interfaceManager.getInterfaceInfo(remoteIf);
649 if(elanIfMac == null) {
652 List<MacEntry> remoteMacEntries = elanIfMac.getMacEntry();
653 if(remoteMacEntries != null) {
654 for (MacEntry macEntry : remoteMacEntries) {
655 PhysAddress physAddress = macEntry.getMacAddress();
656 ElanUtils.setupRemoteDmacFlow(currentDpn, remoteInterface.getDpId(), remoteInterface.getInterfaceTag(), elanInfo.getElanTag(), physAddress.getValue(), elanInfo.getElanInstanceName());
664 // Install DMAC entry on dst DPN
665 public void installDMacAddressTables(ElanInstance elanInfo, InterfaceInfo interfaceInfo, BigInteger dstDpId) {
666 String interfaceName = interfaceInfo.getInterfaceName();
667 ElanInterfaceMac elanInterfaceMac = ElanUtils.getElanInterfaceMacByInterfaceName(interfaceName);
668 if(elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null) {
669 List<MacEntry> macEntries = elanInterfaceMac.getMacEntry();
670 for(MacEntry macEntry : macEntries) {
671 PhysAddress physAddress = macEntry.getMacAddress();
672 ElanUtils.setupDMacFlowonRemoteDpn(elanInfo, interfaceInfo, dstDpId, physAddress.getValue());
677 public void removeMacAddressTables(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
678 ElanInterfaceMac elanInterfaceMac = ElanUtils.getElanInterfaceMacByInterfaceName(interfaceInfo.getInterfaceName());
679 if(elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null) {
680 List<MacEntry> macEntries = elanInterfaceMac.getMacEntry();
681 for(MacEntry macEntry : macEntries) {
682 ElanUtils.deleteMacFlows(elanInfo, interfaceInfo, macEntry);
687 public void setupElanBroadcastGroups(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
688 List<Bucket> listBucket = new ArrayList<Bucket>();
690 BigInteger dpnId = interfaceInfo.getDpId();
691 long groupId = ElanUtils.getElanRemoteBCGID(elanInfo.getElanTag());
693 DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanInfo.getElanInstanceName(), dpnId);
694 for(String ifName : dpnInterfaces.getInterfaces()) {
695 // In case if there is a InterfacePort in the cache which is not in
696 // operational state, skip processing it
697 InterfaceInfo ifInfo = interfaceManager.getInterfaceInfoFromOperationalDataStore(ifName, interfaceInfo.getInterfaceType());
698 if (ifInfo == null || !isOperational(ifInfo)) {
702 listBucket.add(MDSALUtil.buildBucket(getInterfacePortActions(ifInfo), MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
705 List<Bucket> listBucketInfoRemote = getRemoteBCGroupBuckets(elanInfo, interfaceInfo, bucketId);
706 listBucket.addAll(listBucketInfoRemote);
708 Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, MDSALUtil.buildBucketLists(listBucket));
709 logger.trace("installing the localBroadCast Group:{}", group);
710 // In the case of OVS disconnected we receive null object when we query Interface Operation datastore
711 // so the size of the bucket will be zero
712 if(listBucket.size() == 0) {
713 mdsalManager.syncRemoveGroup(dpnId, group);
715 mdsalManager.syncInstallGroup(dpnId, group, ElanConstants.DELAY_TIME_IN_MILLISECOND);
719 public void setupLocalBroadcastGroups(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
720 List<Bucket> listBucket = new ArrayList<Bucket>();
722 BigInteger dpnId = interfaceInfo.getDpId();
723 long groupId = ElanUtils.getElanLocalBCGID(elanInfo.getElanTag());
725 DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanInfo.getElanInstanceName(), dpnId);
726 for(String ifName : dpnInterfaces.getInterfaces()) {
727 // In case if there is a InterfacePort in the cache which is not in
728 // operational state, skip processing it
729 InterfaceInfo ifInfo = interfaceManager.getInterfaceInfoFromOperationalDataStore(ifName, interfaceInfo.getInterfaceType());
730 if (ifInfo == null || !isOperational(ifInfo)) {
734 listBucket.add(MDSALUtil.buildBucket(getInterfacePortActions(ifInfo), MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
739 Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, MDSALUtil.buildBucketLists(listBucket));
740 logger.trace("installing the localBroadCast Group:{}", group);
741 // In the case of OVS disconnected we receive null object for the Interface Operation datastore
742 // so the size of the bucket will be zero
743 if(listBucket.size() == 0) {
744 mdsalManager.syncRemoveGroup(dpnId, group);
746 mdsalManager.syncInstallGroup(dpnId, group, ElanConstants.DELAY_TIME_IN_MILLISECOND);
750 public void removeLocalBroadcastGroup(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
751 BigInteger dpnId = interfaceInfo.getDpId();
752 long groupId = ElanUtils.getElanLocalBCGID(elanInfo.getElanTag());
753 List<Bucket> listBuckets = new ArrayList<>();
755 listBuckets.add(getLocalBCGroupBucketInfo(interfaceInfo, bucketId));
756 //listBuckets.addAll(getRemoteBCGroupBucketInfos(elanInfo, 1, interfaceInfo));
757 Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, MDSALUtil.buildBucketLists(listBuckets));
758 logger.trace("deleted the localBroadCast Group:{}", group);
759 mdsalManager.syncRemoveGroup(dpnId, group);
762 public void removeElanBroadcastGroup(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
764 List<Bucket> listBuckets = new ArrayList<>();
765 listBuckets.add(getLocalBCGroupBucketInfo(interfaceInfo, bucketId));
767 listBuckets.addAll(getRemoteBCGroupBucketInfos(elanInfo, bucketId, interfaceInfo));
768 BigInteger dpnId = interfaceInfo.getDpId();
769 long groupId = ElanUtils.getElanRemoteBCGID(elanInfo.getElanTag());
770 Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, MDSALUtil.buildBucketLists(listBuckets));
771 logger.trace("deleting the remoteBroadCast group:{}", group);
772 mdsalManager.syncRemoveGroup(dpnId, group);
775 public void setupTerminateServiceTable(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
776 long elanTag = elanInfo.getElanTag();
777 Flow flowEntity = MDSALUtil.buildFlowNew(NwConstants.INTERNAL_TUNNEL_TABLE, getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE, elanTag),
778 5, String.format("%s:%d","ITM Flow Entry ",elanTag), 0, 0, ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(elanTag)), ElanUtils.getTunnelMatchesForServiceId((int)elanTag),
779 getInstructionsForOutGroup(ElanUtils.getElanRemoteBCGID(elanTag)));
781 mdsalManager.installFlow(interfaceInfo.getDpId(), flowEntity);
784 public void setupUnknownDMacTable(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
785 long elanTag = elanInfo.getElanTag();
786 Flow flowEntity = MDSALUtil.buildFlowNew(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, getFlowRef(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, elanTag),
787 5, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_UNKNOWN_DMAC.add(BigInteger.valueOf(elanTag)), getMatchesForElanTag(elanTag),
788 getInstructionsForOutGroup(ElanUtils.getElanRemoteBCGID(elanTag)));
790 mdsalManager.installFlow(interfaceInfo.getDpId(), flowEntity);
793 private void removeStaticELanFlows(final ElanInstance elanInfo, final InterfaceInfo interfaceInfo) {
794 BigInteger dpId = interfaceInfo.getDpId();
795 long elanTag = elanInfo.getElanTag();
797 * If there are not elan ports, remove the unknown smac and default dmac
800 DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanInfo.getElanInstanceName(), dpId);
801 if(dpnInterfaces == null) {
804 List <String> elanInterfaces = dpnInterfaces.getInterfaces();
805 if (elanInterfaces == null || elanInterfaces.isEmpty()) {
807 logger.debug("deleting the elan: {} present on dpId: {}", elanInfo.getElanInstanceName(), dpId);
808 removeDefaultTermFlow(dpId, elanInfo.getElanTag());
809 removeUnknownDmacFlow(dpId, elanInfo);
810 removeElanBroadcastGroup(elanInfo, interfaceInfo);
811 removeLocalBroadcastGroup(elanInfo, interfaceInfo);
812 removeFilterEqualsTable(elanInfo, interfaceInfo);
814 setupElanBroadcastGroups(elanInfo, interfaceInfo);
815 setupLocalBroadcastGroups(elanInfo, interfaceInfo);
816 removeFilterEqualsTable(elanInfo, interfaceInfo);
820 private void removeUnknownDmacFlow(BigInteger dpId, ElanInstance elanInfo) {
821 Flow flow = getUnknownDmacFlowEntity(dpId, elanInfo);
822 mdsalManager.removeFlow(dpId, flow);
825 private void removeDefaultTermFlow(BigInteger dpId, long elanTag) {
826 ElanUtils.removeTerminatingServiceAction(dpId, (int) elanTag);
829 private void bindService(ElanInstance elanInfo, String interfaceName) {
830 // interfaceManager.bindService(interfaceName, ElanUtils.getServiceInfo(elanInfo.getElanInstanceName(), elanInfo.getElanTag(), interfaceName));
832 int priority = ElanConstants.ELAN_SERVICE_PRIORITY;
833 int instructionKey = 0;
834 List<Instruction> instructions = new ArrayList<Instruction>();
835 instructions.add(MDSALUtil.buildAndGetWriteMetadaInstruction(ElanUtils.getElanMetadataLabel(elanInfo.getElanTag()), MetaDataUtil.METADATA_MASK_SERVICE, ++instructionKey));
836 instructions.add(MDSALUtil.buildAndGetGotoTableInstruction(ElanConstants.ELAN_SMAC_TABLE, ++instructionKey));
839 ElanUtils.getBoundServices(String.format("%s.%s.%s", "vpn",elanInfo.getElanInstanceName(), interfaceName),
840 ElanConstants.ELAN_SERVICE_INDEX, priority,
841 ElanConstants.COOKIE_ELAN_INGRESS_TABLE, instructions);
842 ElanUtils.syncWrite(broker, LogicalDatastoreType.CONFIGURATION,
843 ElanUtils.buildServiceId(interfaceName, ElanConstants.ELAN_SERVICE_INDEX), serviceInfo);
846 private void unbindService(ElanInstance elanInfo, String interfaceName) {
847 ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION,
848 ElanUtils.buildServiceId(interfaceName,ElanConstants.ELAN_SERVICE_INDEX),
849 ElanUtils.DEFAULT_CALLBACK);
852 private void unbindService(ElanInstance elanInfo, String interfaceName, int vlanId) {
853 ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION,
854 ElanUtils.buildServiceId(interfaceName,ElanConstants.ELAN_SERVICE_INDEX),
855 ElanUtils.DEFAULT_CALLBACK);
858 private Flow getUnknownDmacFlowEntity(BigInteger dpId, ElanInstance elanInfo) {
859 long elanTag = elanInfo.getElanTag();
860 List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
862 mkMatches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
863 ElanUtils.getElanMetadataLabel(elanTag),
864 MetaDataUtil.METADATA_MASK_SERVICE }));
866 List<Instruction> mkInstructions = new ArrayList<Instruction>();
867 List <Action> actionsInfos = new ArrayList <Action> ();
868 actionsInfos.add(new ActionInfo(ActionType.group, new String[]{Long.toString(ElanUtils.getElanRemoteBCGID(elanTag))}, 0).buildAction());
869 mkInstructions.add(ElanUtils.getWriteActionInstruction(actionsInfos));
871 Flow flow = MDSALUtil.buildFlowNew(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, getFlowRef(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, elanTag),
872 5, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_UNKNOWN_DMAC.add(BigInteger.valueOf(elanTag)),
873 mkMatches, mkInstructions);
877 private String getFlowRef(long tableId, long elanTag) {
878 return new StringBuffer().append(tableId).append(elanTag).toString();
881 private List<Action> getInterfacePortActions(InterfaceInfo interfaceInfo) {
882 List<Action> listAction = new ArrayList<Action>();
884 listAction.add((new ActionInfo(ActionType.set_field_tunnel_id, new BigInteger[] {BigInteger.valueOf(interfaceInfo.getInterfaceTag())}, actionKey)).buildAction());
886 listAction.add((new ActionInfo(ActionType.nx_resubmit, new String[] {Short.toString((short)55)}, actionKey)).buildAction());
890 private void updateElanDpnInterfacesList(String elanInstanceName, BigInteger dpId, List<String> interfaceNames) {
891 DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId)
892 .setInterfaces(interfaceNames).setKey(new DpnInterfacesKey(dpId)).build();
893 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId),
897 private List<String> createElanInterfacesList(String elanInstanceName, String interfaceName, BigInteger dpId) {
898 List<String> interfaceNames = new ArrayList<String>();
899 interfaceNames.add(interfaceName);
900 DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId)
901 .setInterfaces(interfaceNames).setKey(new DpnInterfacesKey(dpId)).build();
902 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId),
904 return interfaceNames;
907 private void createElanInterfaceTablesList(String interfaceName) {
908 InstanceIdentifier<ElanInterfaceMac> elanInterfaceMacTables = ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName);
909 Optional<ElanInterfaceMac> interfaceMacTables = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanInterfaceMacTables);
910 // Adding new Elan Interface Port to the operational DataStore without Static-Mac Entries..
911 if(!interfaceMacTables.isPresent()) {
912 ElanInterfaceMac elanInterfaceMacTable = new ElanInterfaceMacBuilder().setElanInterface(interfaceName).setKey(new ElanInterfaceMacKey(interfaceName)).build();
913 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName),
914 elanInterfaceMacTable);
918 private void createElanStateList(String elanInstanceName, String interfaceName) {
919 InstanceIdentifier<Elan> elanInstance = ElanUtils.getElanInstanceOperationalDataPath(elanInstanceName);
920 Optional<Elan> elanInterfaceLists = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanInstance);
921 // Adding new Elan Interface Port to the operational DataStore without Static-Mac Entries..
922 if(elanInterfaceLists.isPresent()) {
923 List<String> interfaceLists = elanInterfaceLists.get().getElanInterfaces();
924 if(interfaceLists == null) {
925 interfaceLists = new ArrayList<>();
927 interfaceLists.add(interfaceName);
928 Elan elanState = new ElanBuilder().setName(elanInstanceName).setElanInterfaces(interfaceLists).setKey(new ElanKey(elanInstanceName)).build();
929 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanInstanceName), elanState);
933 private boolean isOperational(InterfaceInfo interfaceInfo) {
934 return ((interfaceInfo.getOpState() == InterfaceInfo.InterfaceOpState.UP) && (interfaceInfo.getAdminState() == InterfaceInfo.InterfaceAdminState.ENABLED));
937 protected void updatedIfPrimaryAttributeChanged(ElanInterface elanInterface, boolean isUpdated) {
938 String interfaceName = elanInterface.getName();
939 InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
940 BigInteger dpId = interfaceInfo.getDpId();
941 InstanceIdentifier<ElanInterfaceMac> elanInterfaceId = ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName);
942 Optional<ElanInterfaceMac> existingElanInterface = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanInterfaceId);
943 ElanInstance elanInfo = ElanUtils.getElanInstanceByName(elanInterface.getElanInstanceName());
945 if(!existingElanInterface.isPresent()) {
949 List<MacEntry> macEntries = existingElanInterface.get().getMacEntry();
950 if(macEntries != null && !macEntries.isEmpty()) {
951 for (MacEntry macEntry : macEntries) {
953 ElanUtils.setupMacFlows(elanInfo, interfaceInfo, ElanConstants.STATIC_MAC_TIMEOUT, macEntry.getMacAddress().getValue());
955 ElanUtils.deleteMacFlows(elanInfo, interfaceInfo, macEntry);
960 InstanceIdentifier<DpnInterfaces> dpnInterfaceId = ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInterface.getElanInstanceName(), interfaceInfo.getDpId());
961 Optional<DpnInterfaces> dpnInterfaces = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, dpnInterfaceId);
962 List<String> interfaceLists = dpnInterfaces.get().getInterfaces();
965 interfaceLists.add(elanInterface.getName());
967 interfaceLists.remove(elanInterface.getName());
970 DpnInterfaces updateDpnInterfaces = new DpnInterfacesBuilder().setInterfaces(interfaceLists).setDpId(dpId).setKey(new DpnInterfacesKey(dpId)).build();
971 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, dpnInterfaceId, updateDpnInterfaces);
974 installFlowsAndGroups(elanInfo, interfaceInfo);
976 removeStaticELanFlows(elanInfo, interfaceInfo);
977 unbindService(elanInfo, interfaceName);
981 public void handleTunnelStateEvent(BigInteger srcDpId, BigInteger dstDpId) {
982 ElanDpnInterfaces dpnInterfaceLists = ElanUtils.getElanDpnInterfacesList();
983 Set<String> elanInstancesMap = new HashSet<>();
984 if(dpnInterfaceLists == null) {
987 List<ElanDpnInterfacesList> elanDpnIf = dpnInterfaceLists.getElanDpnInterfacesList();
988 for(ElanDpnInterfacesList elanDpns: elanDpnIf) {
990 String elanName = elanDpns.getElanInstanceName();
991 List<DpnInterfaces> dpnInterfaces = elanDpns.getDpnInterfaces();
992 if(dpnInterfaces == null) {
995 for (DpnInterfaces dpnIf : dpnInterfaces) {
996 if(dpnIf.getDpId().equals(srcDpId) || dpnIf.getDpId().equals(dstDpId)) {
1001 logger.debug("Elan instance:{} is present b/w srcDpn:{} and dstDpn:{}", elanName, srcDpId, dstDpId);
1002 DpnInterfaces dpnInterface = ElanUtils.getElanInterfaceInfoByElanDpn(elanName, srcDpId);
1003 Set<String> interfaceLists = new HashSet<>();
1004 ElanInstance elanInfo = ElanUtils.getElanInstanceByName(elanName);
1005 interfaceLists.addAll(dpnInterface.getInterfaces());
1006 for(String ifName : interfaceLists) {
1007 InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(ifName);
1008 if (isOperational(interfaceInfo)) {
1009 if (interfaceInfo.getDpId().equals(srcDpId) && !elanInstancesMap.contains(elanDpns.getElanInstanceName())) {
1010 elanInstancesMap.add(elanDpns.getElanInstanceName());
1011 elanInterfaceManager.updateRemoteBCGrouponDpnTunnelEvent(elanInfo, interfaceInfo, dstDpId);
1013 elanInterfaceManager.installDMacAddressTables(elanInfo, interfaceInfo, dstDpId);
1021 public void handleInterfaceUpated(InterfaceInfo interfaceInfo, ElanInstance elanInstance, boolean isStateUp) {
1022 BigInteger dpId = interfaceInfo.getDpId();
1023 String elanName = elanInstance.getElanInstanceName();
1024 String ifName = interfaceInfo.getInterfaceName();
1025 logger.trace("Handling interface update event for interface with info {} , state {}", interfaceInfo, isStateUp);
1028 DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanName, dpId);
1029 if(dpnInterfaces == null) {
1030 createElanInterfacesList(elanName, interfaceInfo.getInterfaceName(), dpId);
1032 List<String> dpnElanInterfaces = dpnInterfaces.getInterfaces();
1033 dpnElanInterfaces.add(interfaceInfo.getInterfaceName());
1034 DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId)
1035 .setInterfaces(dpnElanInterfaces).setKey(new DpnInterfacesKey(dpId)).build();
1036 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanName, interfaceInfo.getDpId()), dpnInterface);
1039 logger.trace("ElanInterface Service is installed for interface:{}", ifName);
1040 elanInterfaceManager.installFlowsAndGroups(elanInstance, interfaceInfo);
1041 elanInterfaceManager.installMacAddressTables(elanInstance, interfaceInfo);
1044 DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanName, dpId);
1045 if(dpnInterfaces != null) {
1046 List<String> dpnElanInterfaces = dpnInterfaces.getInterfaces();
1047 dpnElanInterfaces.remove(interfaceInfo.getInterfaceName());
1048 DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId)
1049 .setInterfaces(dpnElanInterfaces).setKey(new DpnInterfacesKey(dpId)).build();
1050 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanName, interfaceInfo.getDpId()), dpnInterface);
1052 logger.trace("ElanInterface Service is removed for the interface:{}", ifName);
1053 elanInterfaceManager.removeMacAddressTables(elanInstance, interfaceInfo);
1054 elanInterfaceManager.removeFlowsAndGroups(elanInstance, interfaceInfo);
1058 private List<MatchInfo> getMatchesForFilterEqualsLPortTag(int LportTag) {
1059 List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
1060 // Matching metadata
1061 mkMatches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
1062 MetaDataUtil.getLportTagMetaData(LportTag),
1063 MetaDataUtil.METADATA_MASK_LPORT_TAG }));
1064 mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[] {BigInteger.valueOf(LportTag)}));
1069 private List<MatchInfo> getTunnelIdMatchForFilterEqualsLPortTag(int LportTag) {
1070 List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
1071 // Matching metadata
1072 mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[] {
1073 BigInteger.valueOf(LportTag)}));
1079 private List<Instruction> getInstructionsDrop() {
1080 List<Instruction> mkInstructions = new ArrayList<Instruction>();
1081 List <Action> actionsInfos = new ArrayList <Action> ();
1082 actionsInfos.add(new ActionInfo(ActionType.drop_action, new String[]{}).buildAction());
1083 mkInstructions.add(ElanUtils.getWriteActionInstruction(actionsInfos));
1084 return mkInstructions;