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.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.ElanUtils;
19 import org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo;
20 import org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo.InterfaceType;
21 import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
22 import org.opendaylight.vpnservice.itm.api.IITMProvider;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.services.info.BoundServices;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
26 import org.opendaylight.vpnservice.mdsalutil.*;
27 import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.ElanDpnInterfaces;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.ElanForwardingTables;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.ElanInterfaces;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan._interface.forwarding.entries.ElanInterfaceMac;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan._interface.forwarding.entries.ElanInterfaceMacBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan._interface.forwarding.entries.ElanInterfaceMacKey;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesList;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfaces;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfacesBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfacesKey;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.forwarding.tables.MacTable;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.forwarding.tables.MacTableKey;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstance;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstanceBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.interfaces.ElanInterface;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.state.Elan;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.state.ElanBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.state.ElanKey;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntry;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntryBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntryKey;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetEgressActionsForInterfaceInputBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetEgressActionsForInterfaceOutput;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.OdlInterfaceRpcService;
55 import org.opendaylight.yangtools.concepts.ListenerRegistration;
56 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
57 import org.slf4j.Logger;
58 import org.slf4j.LoggerFactory;
60 import java.math.BigInteger;
62 import java.util.concurrent.ConcurrentHashMap;
63 import java.util.concurrent.ConcurrentLinkedQueue;
66 public class ElanInterfaceManager extends AbstractDataChangeListener<ElanInterface> implements AutoCloseable {
68 private static ElanInterfaceManager elanInterfaceManager = new ElanInterfaceManager();
69 private ListenerRegistration<DataChangeListener> elanInterfaceListenerRegistration;
70 private ListenerRegistration<DataChangeListener> itmInterfaceListenerRegistration;
71 private OdlInterfaceRpcService interfaceManagerRpcService;
72 private DataBroker broker;
73 private IMdsalApiManager mdsalManager;
74 private IInterfaceManager interfaceManager;
75 private IdManagerService idManager;
76 private IITMProvider itmManager;
77 private ElanForwardingEntriesHandler elanForwardingEntriesHandler;
78 private Map<String, ConcurrentLinkedQueue<ElanInterface>> unProcessedElanInterfaces =
79 new ConcurrentHashMap<String, ConcurrentLinkedQueue<ElanInterface>> ();
81 private static final Logger logger = LoggerFactory.getLogger(ElanInterfaceManager.class);
83 public ElanInterfaceManager() {
84 super(ElanInterface.class);
87 public static ElanInterfaceManager getElanInterfaceManager() {
88 return elanInterfaceManager;
91 public void setMdSalApiManager(IMdsalApiManager mdsalManager) {
92 this.mdsalManager = mdsalManager;
95 public void setInterfaceManagerRpcService(OdlInterfaceRpcService ifManager) {
96 this.interfaceManagerRpcService = ifManager;
99 public void setElanForwardingEntriesHandler(ElanForwardingEntriesHandler elanForwardingEntriesHandler) {
100 this.elanForwardingEntriesHandler = elanForwardingEntriesHandler;
103 public void setInterfaceManager(IInterfaceManager interfaceManager) {
104 this.interfaceManager = interfaceManager;
107 public void setDataBroker(DataBroker broker) {
108 this.broker = broker;
111 public void setIITMManager(IITMProvider itmManager) {
112 this.itmManager = itmManager;
116 public void close() throws Exception {
117 if (elanInterfaceListenerRegistration != null) {
119 elanInterfaceListenerRegistration.close();
120 } catch (final Exception e) {
121 logger.error("Error when cleaning up DataChangeListener.", e);
123 elanInterfaceListenerRegistration = null;
127 public void registerListener() {
129 elanInterfaceListenerRegistration = broker.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
130 getElanInterfaceWildcardPath(), ElanInterfaceManager.this, DataChangeScope.SUBTREE);
131 } catch (final Exception e) {
132 logger.error("ELAN Interface DataChange listener registration failed !", e);
133 throw new IllegalStateException("ELAN Interface registration Listener failed.", e);
137 private InstanceIdentifier<?> getElanInterfaceWildcardPath() {
138 return InstanceIdentifier.create(ElanInterfaces.class).child(ElanInterface.class);
141 public void setIdManager(IdManagerService idManager) {
142 this.idManager = idManager;
146 protected void remove(InstanceIdentifier<ElanInterface> identifier, ElanInterface del) {
147 String interfaceName = del.getName();
148 ElanInstance elanInfo = ElanUtils.getElanInstanceByName(del.getElanInstanceName());
149 removeElanInterface(elanInfo, interfaceName);
152 public void removeElanService(ElanInterface del, int vlanId) {
153 ElanInstance elanInstance = ElanUtils.getElanInstanceByName(del.getElanInstanceName());
154 String interfaceName = del.getName();
155 InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfoFromOperationalDataStore(interfaceName, InterfaceType.VLAN_INTERFACE);
156 removeElanInterface(elanInstance, interfaceInfo);
157 unbindService(elanInstance, interfaceName, vlanId);
160 public void removeElanInterface(ElanInstance elanInfo, String interfaceName) {
161 String elanName = elanInfo.getElanInstanceName();
162 InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
163 if (interfaceInfo == null) {
164 ElanInterfaceMac elanInterfaceMac = ElanUtils.getElanInterfaceMacByInterfaceName(interfaceName);
165 if(elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null) {
166 List<MacEntry> macEntries = elanInterfaceMac.getMacEntry();
167 for(MacEntry macEntry : macEntries) {
168 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getMacEntryOperationalDataPath(elanName, macEntry.getMacAddress()));
171 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName));
172 Elan elanState = ElanUtils.getElanByName(elanName);
173 List<String> elanInterfaces = elanState.getElanInterfaces();
174 elanInterfaces.remove(interfaceName);
175 if(elanInterfaces.isEmpty()) {
176 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanName));
177 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanMacTableOperationalDataPath(elanName));
178 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInfoEntriesOperationalDataPath(elanInfo.getElanTag()));
179 ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION, ElanUtils.getElanInstanceConfigurationDataPath(elanName));
181 Elan updateElanState = new ElanBuilder().setElanInterfaces(elanInterfaces).setName(elanName).setKey(new ElanKey(elanName)).build();
182 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanName), updateElanState);
186 removeElanInterface(elanInfo, interfaceInfo);
187 unbindService(elanInfo, interfaceName);
190 private void removeElanInterface(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
192 BigInteger dpId = interfaceInfo.getDpId();
193 String elanName = elanInfo.getElanInstanceName();
194 String interfaceName = interfaceInfo.getInterfaceName();
195 Elan elanState = ElanUtils.getElanByName(elanName);
196 logger.debug("Removing the Interface:{} from elan:{}", interfaceName, elanName);
197 InstanceIdentifier<ElanInterfaceMac> elanInterfaceId = ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName);
198 Optional<ElanInterfaceMac> existingElanInterface = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanInterfaceId);
199 if(existingElanInterface.isPresent()) {
200 List<MacEntry> macEntries = existingElanInterface.get().getMacEntry();
201 if(macEntries != null && !macEntries.isEmpty()) {
202 for (MacEntry macEntry : macEntries) {
203 logger.debug("removing the mac-entry:{} present on elanInterface:{}", macEntry.getMacAddress().getValue(), interfaceName);
204 elanForwardingEntriesHandler.deleteElanInterfaceForwardingEntries(elanInfo, interfaceInfo, macEntry);
210 *This condition check is mainly to get DPN-ID in pre-provision deletion scenario after stopping CSS
212 if(dpId.equals(ElanConstants.INVALID_DPN)) {
213 ElanDpnInterfacesList elanDpnInterfacesList = ElanUtils.getElanDpnInterfacesList(elanName);
214 if(elanDpnInterfacesList != null && !elanDpnInterfacesList.getDpnInterfaces().isEmpty()) {
215 List<DpnInterfaces> dpnIfList = elanDpnInterfacesList.getDpnInterfaces();
216 for (DpnInterfaces dpnInterface : dpnIfList) {
217 DpnInterfaces dpnIfLists = ElanUtils.getElanInterfaceInfoByElanDpn(elanName, dpnInterface.getDpId());
218 if (dpnIfLists.getInterfaces().contains(interfaceName)) {
219 logger.debug("deleting the elanInterface from the ElanDpnInterface cache in pre-provision scenario of elan:{} dpn:{} interfaceName:{}", elanName, dpId, interfaceName);
220 removeElanDpnInterfaceFromOperationalDataStore(elanName, dpId, interfaceName);
226 removeElanDpnInterfaceFromOperationalDataStore(elanName, dpId, interfaceName);
229 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, elanInterfaceId);
230 List<String> elanInterfaces = elanState.getElanInterfaces();
231 elanInterfaces.remove(interfaceName);
232 removeStaticELanFlows(elanInfo, interfaceInfo);
233 if(elanInterfaces.isEmpty()) {
234 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanName));
235 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnOperationDataPath(elanName));
236 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanMacTableOperationalDataPath(elanName));
237 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInfoEntriesOperationalDataPath(elanInfo.getElanTag()));
238 //ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION, ElanUtils.getElanInstanceConfigurationDataPath(elanName));
240 Elan updateElanState = new ElanBuilder().setElanInterfaces(elanInterfaces).setName(elanName).setKey(new ElanKey(elanName)).build();
241 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanName), updateElanState);
245 private void removeElanDpnInterfaceFromOperationalDataStore(String elanName, BigInteger dpId, String interfaceName) {
246 DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanName, dpId);
247 if(dpnInterfaces != null) {
248 List<String> interfaceLists = dpnInterfaces.getInterfaces();
249 interfaceLists.remove(interfaceName);
250 updateElanDpnInterfacesList(elanName, dpId, interfaceLists);
255 protected void update(InstanceIdentifier<ElanInterface> identifier, ElanInterface original, ElanInterface update) {
256 // updating the static-Mac Entries for the existing elanInterface
257 String elanName = update.getElanInstanceName();
258 String interfaceName = update.getName();
259 InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
260 List<PhysAddress> existingPhysAddress = original.getStaticMacEntries();
261 List<PhysAddress> updatedPhysAddress = update.getStaticMacEntries();
262 if(updatedPhysAddress != null && !updatedPhysAddress.isEmpty()) {
263 List<PhysAddress> existingClonedPhyAddress = new ArrayList<>();
264 if(existingPhysAddress != null && !existingPhysAddress.isEmpty()) {
265 existingClonedPhyAddress.addAll(0, existingPhysAddress);
266 existingPhysAddress.removeAll(updatedPhysAddress);
267 updatedPhysAddress.removeAll(existingClonedPhyAddress);
268 // removing the PhyAddress which are not presented in the updated List
269 for(PhysAddress physAddress: existingPhysAddress) {
270 removeInterfaceStaticMacEntires(elanName, interfaceName, physAddress);
273 // Adding the new PhysAddress which are presented in the updated List
274 if(updatedPhysAddress.size() > 0) {
275 for(PhysAddress physAddress: updatedPhysAddress) {
276 InstanceIdentifier<MacEntry> macId = getMacEntryOperationalDataPath(elanName, physAddress);
277 Optional<MacEntry> existingMacEntry = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, macId);
278 if(existingMacEntry.isPresent()) {
279 elanForwardingEntriesHandler.updateElanInterfaceForwardingTablesList(elanName, interfaceName, existingMacEntry.get().getInterface(), existingMacEntry.get());
281 elanForwardingEntriesHandler.addElanInterfaceForwardingTableList(ElanUtils.getElanInstanceByName(elanName), interfaceName, physAddress);
285 } else if(existingPhysAddress != null && !existingPhysAddress.isEmpty()) {
286 for( PhysAddress physAddress : existingPhysAddress) {
287 removeInterfaceStaticMacEntires(elanName, interfaceName, physAddress);
293 protected void add(InstanceIdentifier<ElanInterface> identifier, ElanInterface elanInterfaceAdded) {
294 String elanInstanceName = elanInterfaceAdded.getElanInstanceName();
295 String interfaceName = elanInterfaceAdded.getName();
296 InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
297 ElanInstance elanInstance = ElanUtils.getElanInstanceByName(elanInstanceName);
299 if (elanInstance == null) {
300 elanInstance = new ElanInstanceBuilder().setElanInstanceName(elanInstanceName).setDescription(elanInterfaceAdded.getDescription()).build();
301 //Add the ElanInstance in the Configuration data-store
302 ElanUtils.UpdateOperationalDataStore(broker, idManager, elanInstance);
303 elanInstance = ElanUtils.getElanInstanceByName(elanInstanceName);
307 Long elanTag = elanInstance.getElanTag();
308 // If elan tag is not updated, then put the elan interface into unprocessed entry map and entry. Let entries
309 // in this map get processed during ELAN update DCN.
310 if (elanTag == null) {
311 ConcurrentLinkedQueue<ElanInterface> elanInterfaces = unProcessedElanInterfaces.get(elanInstanceName);
312 if (elanInterfaces == null) {
313 elanInterfaces = new ConcurrentLinkedQueue<ElanInterface>();
315 elanInterfaces.add(elanInterfaceAdded);
316 unProcessedElanInterfaces.put(elanInstanceName, elanInterfaces);
319 addElanInterface(elanInterfaceAdded, interfaceInfo, elanInstance);
322 void handleunprocessedElanInterfaces(ElanInstance elanInstance) {
323 Queue<ElanInterface> elanInterfaces = unProcessedElanInterfaces.get(elanInstance.getElanInstanceName());
324 if (elanInterfaces == null || elanInterfaces.isEmpty()) {
327 for (ElanInterface elanInterface: elanInterfaces) {
328 String interfaceName = elanInterface.getName();
329 InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
330 addElanInterface(elanInterface, interfaceInfo, elanInstance);
334 void addElanInterface(ElanInterface elanInterface, InterfaceInfo interfaceInfo, ElanInstance elanInstance) {
335 String interfaceName = elanInterface.getName();
336 String elanInstanceName = elanInterface.getElanInstanceName();
337 List<PhysAddress> staticMacAddresses = elanInterface.getStaticMacEntries();
338 Elan elanInfo = ElanUtils.getElanByName(elanInstanceName);
339 BigInteger dpId = null;
340 if(elanInfo == null) {
341 ElanUtils.UpdateOperationalDataStore(broker, idManager, elanInstance);
343 if(interfaceInfo != null) {
344 dpId = interfaceInfo.getDpId();
346 if(dpId != null && !dpId.equals(ElanConstants.INVALID_DPN)) {
347 InstanceIdentifier<DpnInterfaces> elanDpnInterfaces = ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId);
348 Optional<DpnInterfaces> existingElanDpnInterfaces = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanDpnInterfaces);
349 if (!existingElanDpnInterfaces.isPresent()) {
350 createElanInterfacesList(elanInstanceName, interfaceName, dpId);
352 List<String> elanInterfaces = existingElanDpnInterfaces.get().getInterfaces();
353 elanInterfaces.add(interfaceName);
354 updateElanDpnInterfacesList(elanInstanceName, dpId, elanInterfaces);
358 // add code to install Local/Remote BC group, unknow DMAC entry, terminating service table flow entry
359 // call bindservice of interfacemanager to create ingress table flow enty.
360 //Add interface to the ElanInterfaceForwardingEntires Container
361 createElanInterfaceTablesList(interfaceName);
362 createElanStateList(elanInstanceName, interfaceName);
363 if(interfaceInfo != null) {
364 installFlowsAndGroups(elanInstance, interfaceInfo);
366 // add the static mac addresses
367 if(staticMacAddresses != null) {
368 for (PhysAddress physAddress : staticMacAddresses) {
369 InstanceIdentifier<MacEntry> macId = getMacEntryOperationalDataPath(elanInstanceName, physAddress);
370 Optional<MacEntry> existingMacEntry = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, macId);
371 if (existingMacEntry.isPresent()) {
372 elanForwardingEntriesHandler.updateElanInterfaceForwardingTablesList(elanInstanceName, interfaceName, existingMacEntry.get().getInterface(), existingMacEntry.get());
374 elanForwardingEntriesHandler.addElanInterfaceForwardingTableList(elanInstance, interfaceName, physAddress);
376 if(interfaceInfo != null && isOperational(interfaceInfo)) {
377 logger.debug("Installing Static Mac-Entry on the Elan Interface:{} with MacAddress:{}", interfaceInfo, physAddress.getValue());
378 ElanUtils.setupMacFlows(elanInstance, interfaceInfo, ElanConstants.STATIC_MAC_TIMEOUT, physAddress.getValue());
384 private Map<BigInteger, List<String>> readFePortsDbForElan(String elanName) {
385 ElanDpnInterfacesList elanDpnInterfacesList = ElanUtils.getElanDpnInterfacesList(elanName);
386 HashMap<BigInteger, List<String>> fePortsDb = Maps.newHashMap();
387 if (elanDpnInterfacesList == null) {
390 List<DpnInterfaces> dpnInterfaces = elanDpnInterfacesList.getDpnInterfaces();
391 if (dpnInterfaces == null) {
394 for (DpnInterfaces dpnInterface : dpnInterfaces) {
395 fePortsDb.put(dpnInterface.getDpId(), dpnInterface.getInterfaces());
400 protected void removeInterfaceStaticMacEntires(String elanInstanceName, String interfaceName, PhysAddress physAddress) {
401 InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
402 InstanceIdentifier<MacEntry> macId = getMacEntryOperationalDataPath(elanInstanceName, physAddress);
403 Optional<MacEntry> existingMacEntry = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, macId);
405 if(!existingMacEntry.isPresent()) {
409 MacEntry macEntry = new MacEntryBuilder().setMacAddress(physAddress).setInterface(interfaceName).setKey(new MacEntryKey(physAddress)).build();
410 elanForwardingEntriesHandler.deleteElanInterfaceForwardingEntries(ElanUtils.getElanInstanceByName(elanInstanceName), interfaceInfo, macEntry);
411 elanForwardingEntriesHandler.deleteElanInterfaceMacForwardingEntries(interfaceName, physAddress);
415 private InstanceIdentifier<MacEntry> getMacEntryOperationalDataPath(String elanName, PhysAddress physAddress) {
416 return InstanceIdentifier.builder(ElanForwardingTables.class).child(MacTable.class,
417 new MacTableKey(elanName)).child(MacEntry.class, new MacEntryKey(physAddress)).build();
420 public void installFlowsAndGroups(final ElanInstance elanInfo, final InterfaceInfo interfaceInfo) {
421 if (isOperational(interfaceInfo)) {
423 // LocalBroadcast Group creation with elan-Interfaces
424 setupLocalBroadcastGroups(elanInfo, interfaceInfo);
426 //Terminating Service , UnknownDMAC Table.
427 setupTerminateServiceTable(elanInfo, interfaceInfo);
428 setupUnknownDMacTable(elanInfo, interfaceInfo);
429 setupFilterEqualsTable(elanInfo, interfaceInfo);
430 // bind the Elan service to the Interface
431 bindService(elanInfo, interfaceInfo.getInterfaceName());
433 //update the remote-DPNs remoteBC group entry with Tunnels
434 setRemoteBCGrouponOtherDpns(elanInfo, interfaceInfo);
438 public void setupFilterEqualsTable(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
439 int ifTag = interfaceInfo.getInterfaceTag();
440 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(interfaceInfo.getDpId(), ElanConstants.ELAN_FILTER_EQUALS_TABLE, getFlowRef(ElanConstants.ELAN_FILTER_EQUALS_TABLE, ifTag),
441 9, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_FILTER_EQUALS.add(BigInteger.valueOf(ifTag)), getTunnelIdMatchForFilterEqualsLPortTag(ifTag),
442 getInstructionsInPortForOutGroup(interfaceInfo.getInterfaceName()));
444 mdsalManager.installFlow(flowEntity);
446 FlowEntity flowEntity1 = MDSALUtil.buildFlowEntity(interfaceInfo.getDpId(), ElanConstants.ELAN_FILTER_EQUALS_TABLE, getFlowRef(ElanConstants.ELAN_FILTER_EQUALS_TABLE, 1000+ifTag),
447 10, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_FILTER_EQUALS.add(BigInteger.valueOf(ifTag)), getMatchesForFilterEqualsLPortTag(ifTag),
448 getInstructionsDrop());
450 mdsalManager.installFlow(flowEntity1);
453 private List<BucketInfo> getRemoteBCGroupBucketInfos(ElanInstance elanInfo,
454 InterfaceInfo interfaceInfo) {
455 BigInteger dpnId = interfaceInfo.getDpId();
456 int elanTag = elanInfo.getElanTag().intValue();
457 List<BucketInfo> listBucketInfo = new ArrayList<BucketInfo>();
458 ElanDpnInterfacesList elanDpns = ElanUtils.getElanDpnInterfacesList(elanInfo.getElanInstanceName());
459 if(elanDpns != null) {
460 List<DpnInterfaces> dpnInterfaceses = elanDpns.getDpnInterfaces();
461 for(DpnInterfaces dpnInterface : dpnInterfaceses) {
462 if(ElanUtils.isDpnPresent(dpnInterface.getDpId()) && dpnInterface.getDpId() != dpnId && dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty()) {
464 //FIXME [ELANBE] Removing ITM API for now, will need this for multi dpn.
465 //List<ActionInfo> listActionInfo = itmManager.ITMIngressGetActions(dpnId, dpnInterface.getDpId(), (int) elanTag);
466 //listBucketInfo.add(new BucketInfo(listActionInfo));
467 } catch (Exception ex) {
468 logger.error( "Logical Group Interface not found between source Dpn - {}, destination Dpn - {} " ,dpnId, dpnInterface.getDpId() );
473 List<ActionInfo> listActionInfo = new ArrayList<ActionInfo>();
474 listActionInfo.add(new ActionInfo(ActionType.group, new String[] {String.valueOf(ElanUtils.getElanLocalBCGID(elanInfo.getElanTag()))}));
475 listBucketInfo.add(new BucketInfo(listActionInfo));
476 return listBucketInfo;
479 public ActionInfo getTunnelIdActionInfo(int interfaceTag) {
480 return new ActionInfo(ActionType.set_field_tunnel_id, new BigInteger[]{BigInteger.valueOf(interfaceTag)});
483 private void setRemoteBCGrouponOtherDpns(ElanInstance elanInfo,
484 InterfaceInfo interfaceInfo) {
485 BigInteger dpnId = interfaceInfo.getDpId();
486 int elanTag = elanInfo.getElanTag().intValue();
487 long groupId = ElanUtils.getElanRemoteBCGID(elanTag);
488 ElanDpnInterfacesList elanDpns = ElanUtils.getElanDpnInterfacesList(elanInfo.getElanInstanceName());
489 if(elanDpns != null) {
490 List<DpnInterfaces> dpnInterfaceses = elanDpns.getDpnInterfaces();
491 for(DpnInterfaces dpnInterface : dpnInterfaceses) {
492 List<BucketInfo> remoteListBucketInfo = new ArrayList<BucketInfo>();
493 if(ElanUtils.isDpnPresent(dpnInterface.getDpId()) && !dpnInterface.getDpId().equals(dpnId) && dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty()) {
494 for(DpnInterfaces otherFes : dpnInterfaceses) {
495 if (ElanUtils.isDpnPresent(otherFes.getDpId()) && otherFes.getDpId() != dpnInterface.getDpId()
496 && otherFes.getInterfaces() != null && ! otherFes.getInterfaces().isEmpty()) {
498 //FIXME [ELANBE] Removing ITM API for now, will need this for multi dpn.
499 //List<ActionInfo> remoteListActionInfo = itmManager.ITMIngressGetActions(dpnInterface.getDpId(), otherFes.getDpId(), (int) elanTag);
500 //remoteListBucketInfo.add(new BucketInfo(remoteListActionInfo));
501 } catch (Exception ex) {
502 logger.error( "Logical Group Interface not found between source Dpn - {}, destination Dpn - {} " ,dpnInterface.getDpId(), otherFes.getDpId() );
507 List<ActionInfo> remoteListActionInfo = new ArrayList<ActionInfo>();
508 remoteListActionInfo.add(new ActionInfo(ActionType.group, new String[] {String.valueOf(ElanUtils.getElanLocalBCGID(elanTag))}));
509 remoteListBucketInfo.add(new BucketInfo(remoteListActionInfo));
510 GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnInterface.getDpId(), groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, remoteListBucketInfo);
511 mdsalManager.installGroup(groupEntity);
517 private void updateRemoteBCGrouponDpnTunnelEvent(ElanInstance elanInfo,
518 InterfaceInfo interfaceInfo, BigInteger dstDpId) {
519 int elanTag = elanInfo.getElanTag().intValue();
520 long groupId = ElanUtils.getElanRemoteBCGID(elanTag);
521 List<DpnInterfaces> elanDpns = ElanUtils.getInvolvedDpnsInElan(elanInfo.getElanInstanceName());
522 if(elanDpns != null) {
523 for(DpnInterfaces dpnInterface : elanDpns) {
524 List<BucketInfo> remoteListBucketInfo = new ArrayList<BucketInfo>();
525 if(ElanUtils.isDpnPresent(dstDpId) && dpnInterface.getDpId().equals(dstDpId) && dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty()) {
527 //FIXME [ELANBE] Removing ITM API for now, will need this for multi dpn.
528 //List<ActionInfo> remoteListActionInfo = itmManager.ITMIngressGetActions(interfaceInfo.getDpId(), dstDpId, (int) elanTag);
529 //remoteListBucketInfo.add(new BucketInfo(remoteListActionInfo));
530 } catch (Exception ex) {
531 logger.error( "Logical Group Interface not found between source Dpn - {}, destination Dpn - {} " ,dpnInterface.getDpId(), dstDpId);
534 List<ActionInfo> remoteListActionInfo = new ArrayList<ActionInfo>();
535 remoteListActionInfo.add(new ActionInfo(ActionType.group, new String[] {String.valueOf(ElanUtils.getElanLocalBCGID(elanTag))}));
536 remoteListBucketInfo.add(new BucketInfo(remoteListActionInfo));
537 GroupEntity groupEntity = MDSALUtil.buildGroupEntity(interfaceInfo.getDpId(), groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, remoteListBucketInfo);
538 mdsalManager.installGroup(groupEntity);
547 * Returns the bucket info with the given interface as the only bucket.
549 private List<BucketInfo> getLocalBCGroupBucketInfo(InterfaceInfo interfaceInfo) {
550 return Lists.newArrayList(new BucketInfo(getInterfacePortActionInfos(interfaceInfo)));
553 private List<MatchInfo> getMatchesForElanTag(Long elanTag) {
554 List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
556 mkMatches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
557 ElanUtils.getElanMetadataLabel(elanTag),
558 MetaDataUtil.METADATA_MASK_SERVICE }));
562 private List<InstructionInfo> getInstructionsForOutGroup(
564 List<InstructionInfo> mkInstructions = new ArrayList<InstructionInfo>();
565 List <ActionInfo> actionsInfos = new ArrayList <ActionInfo> ();
566 actionsInfos.add(new ActionInfo(ActionType.group, new String[]{Long.toString(groupId)}));
567 mkInstructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos));
568 return mkInstructions;
571 public void removeFlowsAndGroups(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
572 removeStaticELanFlows(elanInfo, interfaceInfo);
573 unbindService(elanInfo, interfaceInfo.getInterfaceName());
576 public void installMacAddressTables(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
577 String interfaceName = interfaceInfo.getInterfaceName();
578 BigInteger currentDpn = interfaceInfo.getDpId();
579 ElanInterfaceMac elanInterfaceMac = ElanUtils.getElanInterfaceMacByInterfaceName(interfaceName);
580 if(elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null) {
581 List<MacEntry> macEntries = elanInterfaceMac.getMacEntry();
582 for(MacEntry macEntry : macEntries) {
583 PhysAddress physAddress = macEntry.getMacAddress();
584 ElanUtils.setupMacFlows(elanInfo, interfaceInfo, macEntry.isIsStaticAddress() ? ElanConstants.STATIC_MAC_TIMEOUT : elanInfo.getMacTimeout(), physAddress.getValue());
586 //Programming the remoteDMACFlows
587 ElanDpnInterfacesList elanDpnInterfacesList = ElanUtils.getElanDpnInterfacesList(elanInfo.getElanInstanceName());
588 List<DpnInterfaces> dpnInterfaceLists = elanDpnInterfacesList.getDpnInterfaces();
589 for(DpnInterfaces dpnInterfaces : dpnInterfaceLists){
590 if(dpnInterfaces.getDpId().equals(interfaceInfo.getDpId())) {
593 List<String> remoteElanInterfaces = dpnInterfaces.getInterfaces();
594 for(String remoteIf : remoteElanInterfaces) {
595 ElanInterfaceMac elanIfMac = ElanUtils.getElanInterfaceMacByInterfaceName(remoteIf);
596 InterfaceInfo remoteInterface = interfaceManager.getInterfaceInfo(remoteIf);
597 if(elanIfMac == null) {
600 List<MacEntry> remoteMacEntries = elanIfMac.getMacEntry();
601 if(remoteMacEntries != null) {
602 for (MacEntry macEntry : remoteMacEntries) {
603 PhysAddress physAddress = macEntry.getMacAddress();
604 ElanUtils.setupRemoteDmacFlow(currentDpn, remoteInterface.getDpId(), remoteInterface.getInterfaceTag(), elanInfo.getElanTag(), physAddress.getValue(), elanInfo.getElanInstanceName());
612 // Install DMAC entry on dst DPN
613 public void installDMacAddressTables(ElanInstance elanInfo, InterfaceInfo interfaceInfo, BigInteger dstDpId) {
614 String interfaceName = interfaceInfo.getInterfaceName();
615 ElanInterfaceMac elanInterfaceMac = ElanUtils.getElanInterfaceMacByInterfaceName(interfaceName);
616 if(elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null) {
617 List<MacEntry> macEntries = elanInterfaceMac.getMacEntry();
618 for(MacEntry macEntry : macEntries) {
619 PhysAddress physAddress = macEntry.getMacAddress();
620 ElanUtils.setupDMacFlowonRemoteDpn(elanInfo, interfaceInfo, dstDpId, physAddress.getValue());
625 public void removeMacAddressTables(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
626 ElanInterfaceMac elanInterfaceMac = ElanUtils.getElanInterfaceMacByInterfaceName(interfaceInfo.getInterfaceName());
627 if(elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null) {
628 List<MacEntry> macEntries = elanInterfaceMac.getMacEntry();
629 for(MacEntry macEntry : macEntries) {
630 ElanUtils.deleteMacFlows(elanInfo, interfaceInfo, macEntry);
635 public void setupLocalBroadcastGroups(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
636 List<BucketInfo> listBucketInfo = new ArrayList<BucketInfo>();
637 BigInteger dpnId = interfaceInfo.getDpId();
638 long groupId = ElanUtils.getElanLocalBCGID(elanInfo.getElanTag());
640 DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanInfo.getElanInstanceName(), dpnId);
641 for(String ifName : dpnInterfaces.getInterfaces()) {
642 // In case if there is a InterfacePort in the cache which is not in
643 // operational state, skip processing it
644 InterfaceInfo ifInfo = interfaceManager.getInterfaceInfoFromOperationalDataStore(ifName, interfaceInfo.getInterfaceType());
645 if (!isOperational(ifInfo)) {
649 listBucketInfo.add(new BucketInfo(getInterfacePortActionInfos(ifInfo)));
651 GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, listBucketInfo);
652 logger.trace("installing the localBroadCast GroupEntity:{}", groupEntity);
653 mdsalManager.syncInstallGroup(groupEntity, ElanConstants.DELAY_TIME_IN_MILLISECOND);
656 public void removeLocalBroadcastGroup(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
657 BigInteger dpnId = interfaceInfo.getDpId();
658 long groupId = ElanUtils.getElanLocalBCGID(elanInfo.getElanTag());
660 GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, getLocalBCGroupBucketInfo(interfaceInfo));
661 logger.trace("deleted the localBroadCast GroupEntity:{}", groupEntity);
662 mdsalManager.syncRemoveGroup(groupEntity);
665 public void removeRemoteBroadcastGroup(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
666 List<BucketInfo> listBucketInfo = getRemoteBCGroupBucketInfos(elanInfo, interfaceInfo);
667 BigInteger dpnId = interfaceInfo.getDpId();
668 long groupId = ElanUtils.getElanRemoteBCGID(elanInfo.getElanTag());
669 GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, listBucketInfo);
670 logger.trace("deleting the remoteBroadCast GroupEntity:{}", groupEntity);
671 mdsalManager.syncRemoveGroup(groupEntity);
674 public void setupTerminateServiceTable(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
675 long elanTag = elanInfo.getElanTag();
676 //FIXME [ELANBE] Removing ITM API for now, will need this for multi dpn.
677 // FlowEntity flowEntity = MDSALUtil.buildFlowEntity(interfaceInfo.getDpId(), ITMConstants.TERMINATING_SERVICE_TABLE, getFlowRef(ITMConstants.TERMINATING_SERVICE_TABLE, elanTag),
678 // 5, elanInfo.getElanInstanceName(), 0, 0, ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(elanTag)), itmManager.getTunnelMatchesForServiceId(elanTag),
679 // getInstructionsForOutGroup(ElanUtils.getElanLocalBCGID(elanTag)));
681 // mdsalManager.installFlow(flowEntity);
684 public void setupUnknownDMacTable(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
685 long elanTag = elanInfo.getElanTag();
686 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(interfaceInfo.getDpId(), ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, getFlowRef(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, elanTag),
687 5, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_UNKNOWN_DMAC.add(BigInteger.valueOf(elanTag)), getMatchesForElanTag(elanTag),
688 getInstructionsForOutGroup(ElanUtils.getElanLocalBCGID(elanTag)));
690 mdsalManager.installFlow(flowEntity);
693 private void removeStaticELanFlows(final ElanInstance elanInfo, final InterfaceInfo interfaceInfo) {
694 BigInteger dpId = interfaceInfo.getDpId();
695 long elanTag = elanInfo.getElanTag();
697 * If there are not elan ports, remove the unknown smac and default dmac
700 DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanInfo.getElanInstanceName(), dpId);
701 if(dpnInterfaces == null) {
704 List <String> elanInterfaces = dpnInterfaces.getInterfaces();
705 if (elanInterfaces == null || elanInterfaces.isEmpty()) {
707 logger.debug("deleting the elan: {} present on dpId: {}", elanInfo.getElanInstanceName(), dpId);
708 removeDefaultTermFlow(dpId, elanInfo.getElanTag());
709 removeUnknownDmacFlow(dpId, elanInfo);
710 removeRemoteBroadcastGroup(elanInfo, interfaceInfo);
711 removeLocalBroadcastGroup(elanInfo, interfaceInfo);
713 setupLocalBroadcastGroups(elanInfo, interfaceInfo);
717 private void removeUnknownDmacFlow(BigInteger dpId, ElanInstance elanInfo) {
718 FlowEntity flowEntity = getUnknownDmacFlowEntity(dpId, elanInfo);
719 mdsalManager.syncRemoveFlow(flowEntity, ElanConstants.DELAY_TIME_IN_MILLISECOND);
722 private void removeDefaultTermFlow(BigInteger dpId, long elanTag) {
723 //FIXME [ELANBE] Removing ITM API for now, will need this for multi dpn.
724 //itmManager.removeTerminatingServiceAction(dpId, (int) elanTag);
727 private void bindService(ElanInstance elanInfo, String interfaceName) {
728 // interfaceManager.bindService(interfaceName, ElanUtils.getServiceInfo(elanInfo.getElanInstanceName(), elanInfo.getElanTag(), interfaceName));
730 int priority = ElanConstants.ELAN_SERVICE_PRIORITY;
731 int instructionKey = 0;
732 List<Instruction> instructions = new ArrayList<Instruction>();
733 instructions.add(MDSALUtil.buildAndGetWriteMetadaInstruction(ElanUtils.getElanMetadataLabel(elanInfo.getElanTag()), MetaDataUtil.METADATA_MASK_SERVICE, ++instructionKey));
734 instructions.add(MDSALUtil.buildAndGetGotoTableInstruction(ElanConstants.ELAN_SMAC_TABLE, ++instructionKey));
737 ElanUtils.getBoundServices(String.format("%s.%s.%s", "vpn",elanInfo.getElanInstanceName(), interfaceName),
738 ElanConstants.ELAN_SERVICE_INDEX, priority,
739 ElanConstants.COOKIE_ELAN_INGRESS_TABLE, instructions);
740 ElanUtils.syncWrite(broker, LogicalDatastoreType.CONFIGURATION,
741 ElanUtils.buildServiceId(interfaceName, ElanConstants.ELAN_SERVICE_INDEX), serviceInfo);
744 private void unbindService(ElanInstance elanInfo, String interfaceName) {
745 ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION,
746 ElanUtils.buildServiceId(interfaceName,ElanConstants.ELAN_SERVICE_INDEX),
747 ElanUtils.DEFAULT_CALLBACK);
750 private void unbindService(ElanInstance elanInfo, String interfaceName, int vlanId) {
751 ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION,
752 ElanUtils.buildServiceId(interfaceName,ElanConstants.ELAN_SERVICE_INDEX),
753 ElanUtils.DEFAULT_CALLBACK);
756 private FlowEntity getUnknownDmacFlowEntity(BigInteger dpId, ElanInstance elanInfo) {
757 long elanTag = elanInfo.getElanTag();
758 List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
760 mkMatches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
761 ElanUtils.getElanMetadataLabel(elanTag),
762 MetaDataUtil.METADATA_MASK_SERVICE }));
764 List<InstructionInfo> mkInstructions = new ArrayList<InstructionInfo>();
765 List <ActionInfo> actionsInfos = new ArrayList <ActionInfo> ();
766 actionsInfos.add(new ActionInfo(ActionType.group, new String[]{Long.toString(ElanUtils.getElanRemoteBCGID(elanTag))}));
767 mkInstructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos));
769 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, getFlowRef(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, elanTag),
770 5, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_UNKNOWN_DMAC.add(BigInteger.valueOf(elanTag)),
771 mkMatches, mkInstructions);
775 private String getFlowRef(long tableId, long elanTag) {
776 return new StringBuffer().append(tableId).append(elanTag).toString();
779 private List<ActionInfo> getInterfacePortActionInfos(InterfaceInfo interfaceInfo) {
780 List<ActionInfo> listActionInfo = new ArrayList<ActionInfo>();
781 listActionInfo.add(getTunnelIdActionInfo(interfaceInfo.getInterfaceTag()));
782 listActionInfo.add(new ActionInfo(ActionType.nx_resubmit, new String[]{}));
783 return listActionInfo;
786 private void updateElanDpnInterfacesList(String elanInstanceName, BigInteger dpId, List<String> interfaceNames) {
787 if(!interfaceNames.isEmpty()) {
788 DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId)
789 .setInterfaces(interfaceNames).setKey(new DpnInterfacesKey(dpId)).build();
790 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId),
793 MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId));
798 private List<String> createElanInterfacesList(String elanInstanceName, String interfaceName, BigInteger dpId) {
799 List<String> interfaceNames = new ArrayList<String>();
800 interfaceNames.add(interfaceName);
801 DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId)
802 .setInterfaces(interfaceNames).setKey(new DpnInterfacesKey(dpId)).build();
803 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId),
805 return interfaceNames;
808 private void createElanInterfaceTablesList(String interfaceName) {
809 InstanceIdentifier<ElanInterfaceMac> elanInterfaceMacTables = ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName);
810 Optional<ElanInterfaceMac> interfaceMacTables = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanInterfaceMacTables);
811 // Adding new Elan Interface Port to the operational DataStore without Static-Mac Entries..
812 if(!interfaceMacTables.isPresent()) {
813 ElanInterfaceMac elanInterfaceMacTable = new ElanInterfaceMacBuilder().setElanInterface(interfaceName).setKey(new ElanInterfaceMacKey(interfaceName)).build();
814 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName),
815 elanInterfaceMacTable);
819 private void createElanStateList(String elanInstanceName, String interfaceName) {
820 InstanceIdentifier<Elan> elanInstance = ElanUtils.getElanInstanceOperationalDataPath(elanInstanceName);
821 Optional<Elan> elanInterfaceLists = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanInstance);
822 // Adding new Elan Interface Port to the operational DataStore without Static-Mac Entries..
823 if(elanInterfaceLists.isPresent()) {
824 List<String> interfaceLists = elanInterfaceLists.get().getElanInterfaces();
825 if(interfaceLists == null) {
826 interfaceLists = new ArrayList<>();
828 interfaceLists.add(interfaceName);
829 Elan elanState = new ElanBuilder().setName(elanInstanceName).setElanInterfaces(interfaceLists).setKey(new ElanKey(elanInstanceName)).build();
830 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanInstanceName), elanState);
834 private boolean isOperational(InterfaceInfo interfaceInfo) {
835 return ((interfaceInfo.getOpState() == InterfaceInfo.InterfaceOpState.UP) && (interfaceInfo.getAdminState() == InterfaceInfo.InterfaceAdminState.ENABLED));
838 protected void updatedIfPrimaryAttributeChanged(ElanInterface elanInterface, boolean isUpdated) {
839 String interfaceName = elanInterface.getName();
840 InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
841 BigInteger dpId = interfaceInfo.getDpId();
842 InstanceIdentifier<ElanInterfaceMac> elanInterfaceId = ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName);
843 Optional<ElanInterfaceMac> existingElanInterface = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanInterfaceId);
844 ElanInstance elanInfo = ElanUtils.getElanInstanceByName(elanInterface.getElanInstanceName());
846 if(!existingElanInterface.isPresent()) {
850 List<MacEntry> macEntries = existingElanInterface.get().getMacEntry();
851 if(macEntries != null && !macEntries.isEmpty()) {
852 for (MacEntry macEntry : macEntries) {
854 ElanUtils.setupMacFlows(elanInfo, interfaceInfo, ElanConstants.STATIC_MAC_TIMEOUT, macEntry.getMacAddress().getValue());
856 ElanUtils.deleteMacFlows(elanInfo, interfaceInfo, macEntry);
861 InstanceIdentifier<DpnInterfaces> dpnInterfaceId = ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInterface.getElanInstanceName(), interfaceInfo.getDpId());
862 Optional<DpnInterfaces> dpnInterfaces = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, dpnInterfaceId);
863 List<String> interfaceLists = dpnInterfaces.get().getInterfaces();
866 interfaceLists.add(elanInterface.getName());
868 interfaceLists.remove(elanInterface.getName());
871 DpnInterfaces updateDpnInterfaces = new DpnInterfacesBuilder().setInterfaces(interfaceLists).setDpId(dpId).setKey(new DpnInterfacesKey(dpId)).build();
872 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, dpnInterfaceId, updateDpnInterfaces);
875 installFlowsAndGroups(elanInfo, interfaceInfo);
877 removeStaticELanFlows(elanInfo, interfaceInfo);
878 unbindService(elanInfo, interfaceName);
882 public void handleTunnelStateEvent(BigInteger srcDpId, BigInteger dstDpId) {
883 ElanDpnInterfaces dpnInterfaceLists = ElanUtils.getElanDpnInterfacesList();
884 Set<String> elanInstancesMap = new HashSet<>();
885 if(dpnInterfaceLists == null) {
888 List<ElanDpnInterfacesList> elanDpnIf = dpnInterfaceLists.getElanDpnInterfacesList();
889 for(ElanDpnInterfacesList elanDpns: elanDpnIf) {
891 String elanName = elanDpns.getElanInstanceName();
892 List<DpnInterfaces> dpnInterfaces = elanDpns.getDpnInterfaces();
893 if(dpnInterfaces == null) {
896 for (DpnInterfaces dpnIf : dpnInterfaces) {
897 if(dpnIf.getDpId().equals(srcDpId) || dpnIf.getDpId().equals(dstDpId)) {
902 logger.debug("Elan instance:{} is present b/w srcDpn:{} and dstDpn:{}", elanName, srcDpId, dstDpId);
903 DpnInterfaces dpnInterface = ElanUtils.getElanInterfaceInfoByElanDpn(elanName, srcDpId);
904 Set<String> interfaceLists = new HashSet<>();
905 ElanInstance elanInfo = ElanUtils.getElanInstanceByName(elanName);
906 interfaceLists.addAll(dpnInterface.getInterfaces());
907 for(String ifName : interfaceLists) {
908 InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(ifName);
909 if (isOperational(interfaceInfo)) {
910 if (interfaceInfo.getDpId().equals(srcDpId) && !elanInstancesMap.contains(elanDpns.getElanInstanceName())) {
911 elanInstancesMap.add(elanDpns.getElanInstanceName());
912 elanInterfaceManager.updateRemoteBCGrouponDpnTunnelEvent(elanInfo, interfaceInfo, dstDpId);
914 elanInterfaceManager.installDMacAddressTables(elanInfo, interfaceInfo, dstDpId);
922 public void handleInterfaceUpated(InterfaceInfo interfaceInfo, ElanInstance elanInstance, boolean isStateUp) {
923 BigInteger dpId = interfaceInfo.getDpId();
924 String elanName = elanInstance.getElanInstanceName();
925 String ifName = interfaceInfo.getInterfaceName();
926 logger.trace("Handling interface update event for interface with info {} , state {}", interfaceInfo, isStateUp);
929 DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanName, dpId);
930 if(dpnInterfaces == null) {
931 createElanInterfacesList(elanName, interfaceInfo.getInterfaceName(), dpId);
933 List<String> dpnElanInterfaces = dpnInterfaces.getInterfaces();
934 dpnElanInterfaces.add(interfaceInfo.getInterfaceName());
935 DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId)
936 .setInterfaces(dpnElanInterfaces).setKey(new DpnInterfacesKey(dpId)).build();
937 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanName, interfaceInfo.getDpId()), dpnInterface);
940 logger.trace("ElanInterface Service is installed for interface:{}", ifName);
941 elanInterfaceManager.installFlowsAndGroups(elanInstance, interfaceInfo);
942 elanInterfaceManager.installMacAddressTables(elanInstance, interfaceInfo);
945 DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanName, dpId);
946 if(dpnInterfaces != null) {
947 List<String> dpnElanInterfaces = dpnInterfaces.getInterfaces();
948 dpnElanInterfaces.remove(interfaceInfo.getInterfaceName());
949 DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId)
950 .setInterfaces(dpnElanInterfaces).setKey(new DpnInterfacesKey(dpId)).build();
951 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanName, interfaceInfo.getDpId()), dpnInterface);
953 logger.trace("ElanInterface Service is removed for the interface:{}", ifName);
954 elanInterfaceManager.removeMacAddressTables(elanInstance, interfaceInfo);
955 elanInterfaceManager.removeFlowsAndGroups(elanInstance, interfaceInfo);
959 private List<MatchInfo> getMatchesForFilterEqualsLPortTag(int LportTag) {
960 List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
962 mkMatches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
963 MetaDataUtil.getLportTagMetaData(LportTag),
964 MetaDataUtil.METADATA_MASK_LPORT_TAG }));
965 mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[] {BigInteger.valueOf(LportTag)}));
970 private List<MatchInfo> getTunnelIdMatchForFilterEqualsLPortTag(int LportTag) {
971 List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
973 mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[] {
974 BigInteger.valueOf(LportTag)}));
980 private List<InstructionInfo> getInstructionsInPortForOutGroup(
982 List<InstructionInfo> mkInstructions = new ArrayList<InstructionInfo>();
983 List <ActionInfo> actionsInfos = new ArrayList <ActionInfo> ();
984 actionsInfos.addAll(ElanUtils.getEgressActionsForInterface(ifName));
985 mkInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
986 return mkInstructions;
991 private List<InstructionInfo> getInstructionsDrop() {
992 List<InstructionInfo> mkInstructions = new ArrayList<InstructionInfo>();
993 List <ActionInfo> actionsInfos = new ArrayList <ActionInfo> ();
994 actionsInfos.add(new ActionInfo(ActionType.drop_action, new String[]{}));
995 mkInstructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos));
996 return mkInstructions;