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()));
176 ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION, ElanUtils.getElanInstanceConfigurationDataPath(elanName));
178 Elan updateElanState = new ElanBuilder().setElanInterfaces(elanInterfaces).setName(elanName).setKey(new ElanKey(elanName)).build();
179 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanName), updateElanState);
183 removeElanInterface(elanInfo, interfaceInfo);
184 unbindService(elanInfo, interfaceName);
187 private void removeElanInterface(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
189 BigInteger dpId = interfaceInfo.getDpId();
190 String elanName = elanInfo.getElanInstanceName();
191 String interfaceName = interfaceInfo.getInterfaceName();
192 Elan elanState = ElanUtils.getElanByName(elanName);
193 logger.debug("Removing the Interface:{} from elan:{}", interfaceName, elanName);
194 InstanceIdentifier<ElanInterfaceMac> elanInterfaceId = ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName);
195 Optional<ElanInterfaceMac> existingElanInterface = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanInterfaceId);
196 if(existingElanInterface.isPresent()) {
197 List<MacEntry> macEntries = existingElanInterface.get().getMacEntry();
198 if(macEntries != null && !macEntries.isEmpty()) {
199 for (MacEntry macEntry : macEntries) {
200 logger.debug("removing the mac-entry:{} present on elanInterface:{}", macEntry.getMacAddress().getValue(), interfaceName);
201 elanForwardingEntriesHandler.deleteElanInterfaceForwardingEntries(elanInfo, interfaceInfo, macEntry);
206 *This condition check is mainly to get DPN-ID in pre-provision deletion scenario after stopping CSS
208 if(dpId.equals(ElanConstants.INVALID_DPN)) {
209 ElanDpnInterfacesList elanDpnInterfacesList = ElanUtils.getElanDpnInterfacesList(elanName);
210 if(elanDpnInterfacesList != null && !elanDpnInterfacesList.getDpnInterfaces().isEmpty()) {
211 List<DpnInterfaces> dpnIfList = elanDpnInterfacesList.getDpnInterfaces();
212 for (DpnInterfaces dpnInterface : dpnIfList) {
213 DpnInterfaces dpnIfLists = ElanUtils.getElanInterfaceInfoByElanDpn(elanName, dpnInterface.getDpId());
214 if (dpnIfLists.getInterfaces().contains(interfaceName)) {
215 logger.debug("deleting the elanInterface from the ElanDpnInterface cache in pre-provision scenario of elan:{} dpn:{} interfaceName:{}", elanName, dpId, interfaceName);
216 removeElanDpnInterfaceFromOperationalDataStore(elanName, dpId, interfaceName);
222 removeElanDpnInterfaceFromOperationalDataStore(elanName, dpId, interfaceName);
225 removeStaticELanFlows(elanInfo, interfaceInfo);
226 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, elanInterfaceId);
227 List<String> elanInterfaces = elanState.getElanInterfaces();
228 elanInterfaces.remove(interfaceName);
230 if(elanInterfaces.isEmpty()) {
231 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanName));
232 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnOperationDataPath(elanName));
233 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanMacTableOperationalDataPath(elanName));
234 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInfoEntriesOperationalDataPath(elanInfo.getElanTag()));
235 //ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION, ElanUtils.getElanInstanceConfigurationDataPath(elanName));
237 Elan updateElanState = new ElanBuilder().setElanInterfaces(elanInterfaces).setName(elanName).setKey(new ElanKey(elanName)).build();
238 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanName), updateElanState);
242 private void removeElanDpnInterfaceFromOperationalDataStore(String elanName, BigInteger dpId, String interfaceName) {
243 DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanName, dpId);
244 if(dpnInterfaces != null) {
245 List<String> interfaceLists = dpnInterfaces.getInterfaces();
246 interfaceLists.remove(interfaceName);
247 updateElanDpnInterfacesList(elanName, dpId, interfaceLists);
252 protected void update(InstanceIdentifier<ElanInterface> identifier, ElanInterface original, ElanInterface update) {
253 // updating the static-Mac Entries for the existing elanInterface
254 String elanName = update.getElanInstanceName();
255 String interfaceName = update.getName();
256 InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
257 List<PhysAddress> existingPhysAddress = original.getStaticMacEntries();
258 List<PhysAddress> updatedPhysAddress = update.getStaticMacEntries();
259 if(updatedPhysAddress != null && !updatedPhysAddress.isEmpty()) {
260 List<PhysAddress> existingClonedPhyAddress = new ArrayList<>();
261 if(existingPhysAddress != null && !existingPhysAddress.isEmpty()) {
262 existingClonedPhyAddress.addAll(0, existingPhysAddress);
263 existingPhysAddress.removeAll(updatedPhysAddress);
264 updatedPhysAddress.removeAll(existingClonedPhyAddress);
265 // removing the PhyAddress which are not presented in the updated List
266 for(PhysAddress physAddress: existingPhysAddress) {
267 removeInterfaceStaticMacEntires(elanName, interfaceName, physAddress);
270 // Adding the new PhysAddress which are presented in the updated List
271 if(updatedPhysAddress.size() > 0) {
272 for(PhysAddress physAddress: updatedPhysAddress) {
273 InstanceIdentifier<MacEntry> macId = getMacEntryOperationalDataPath(elanName, physAddress);
274 Optional<MacEntry> existingMacEntry = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, macId);
275 if(existingMacEntry.isPresent()) {
276 elanForwardingEntriesHandler.updateElanInterfaceForwardingTablesList(elanName, interfaceName, existingMacEntry.get().getInterface(), existingMacEntry.get());
278 elanForwardingEntriesHandler.addElanInterfaceForwardingTableList(ElanUtils.getElanInstanceByName(elanName), interfaceName, physAddress);
282 } else if(existingPhysAddress != null && !existingPhysAddress.isEmpty()) {
283 for( PhysAddress physAddress : existingPhysAddress) {
284 removeInterfaceStaticMacEntires(elanName, interfaceName, physAddress);
290 protected void add(InstanceIdentifier<ElanInterface> identifier, ElanInterface elanInterfaceAdded) {
291 String elanInstanceName = elanInterfaceAdded.getElanInstanceName();
292 String interfaceName = elanInterfaceAdded.getName();
293 InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
294 ElanInstance elanInstance = ElanUtils.getElanInstanceByName(elanInstanceName);
296 if (elanInstance == null) {
297 elanInstance = new ElanInstanceBuilder().setElanInstanceName(elanInstanceName).setDescription(elanInterfaceAdded.getDescription()).build();
298 //Add the ElanInstance in the Configuration data-store
299 ElanUtils.UpdateOperationalDataStore(broker, idManager, elanInstance);
300 elanInstance = ElanUtils.getElanInstanceByName(elanInstanceName);
304 Long elanTag = elanInstance.getElanTag();
305 // If elan tag is not updated, then put the elan interface into unprocessed entry map and entry. Let entries
306 // in this map get processed during ELAN update DCN.
307 if (elanTag == null) {
308 ConcurrentLinkedQueue<ElanInterface> elanInterfaces = unProcessedElanInterfaces.get(elanInstanceName);
309 if (elanInterfaces == null) {
310 elanInterfaces = new ConcurrentLinkedQueue<ElanInterface>();
312 elanInterfaces.add(elanInterfaceAdded);
313 unProcessedElanInterfaces.put(elanInstanceName, elanInterfaces);
316 addElanInterface(elanInterfaceAdded, interfaceInfo, elanInstance);
319 void handleunprocessedElanInterfaces(ElanInstance elanInstance) {
320 Queue<ElanInterface> elanInterfaces = unProcessedElanInterfaces.get(elanInstance.getElanInstanceName());
321 if (elanInterfaces == null || elanInterfaces.isEmpty()) {
324 for (ElanInterface elanInterface: elanInterfaces) {
325 String interfaceName = elanInterface.getName();
326 InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
327 addElanInterface(elanInterface, interfaceInfo, elanInstance);
331 void addElanInterface(ElanInterface elanInterface, InterfaceInfo interfaceInfo, ElanInstance elanInstance) {
332 String interfaceName = elanInterface.getName();
333 String elanInstanceName = elanInterface.getElanInstanceName();
334 List<PhysAddress> staticMacAddresses = elanInterface.getStaticMacEntries();
335 Elan elanInfo = ElanUtils.getElanByName(elanInstanceName);
336 BigInteger dpId = null;
337 if(elanInfo == null) {
338 ElanUtils.UpdateOperationalDataStore(broker, idManager, elanInstance);
340 if(interfaceInfo != null) {
341 dpId = interfaceInfo.getDpId();
343 if(dpId != null && !dpId.equals(ElanConstants.INVALID_DPN)) {
344 InstanceIdentifier<DpnInterfaces> elanDpnInterfaces = ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId);
345 Optional<DpnInterfaces> existingElanDpnInterfaces = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanDpnInterfaces);
346 if (!existingElanDpnInterfaces.isPresent()) {
347 createElanInterfacesList(elanInstanceName, interfaceName, dpId);
349 List<String> elanInterfaces = existingElanDpnInterfaces.get().getInterfaces();
350 elanInterfaces.add(interfaceName);
351 updateElanDpnInterfacesList(elanInstanceName, dpId, elanInterfaces);
355 // add code to install Local/Remote BC group, unknow DMAC entry, terminating service table flow entry
356 // call bindservice of interfacemanager to create ingress table flow enty.
357 //Add interface to the ElanInterfaceForwardingEntires Container
358 createElanInterfaceTablesList(interfaceName);
359 createElanStateList(elanInstanceName, interfaceName);
360 if(interfaceInfo != null) {
361 installFlowsAndGroups(elanInstance, interfaceInfo);
363 // add the static mac addresses
364 if(staticMacAddresses != null) {
365 for (PhysAddress physAddress : staticMacAddresses) {
366 InstanceIdentifier<MacEntry> macId = getMacEntryOperationalDataPath(elanInstanceName, physAddress);
367 Optional<MacEntry> existingMacEntry = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, macId);
368 if (existingMacEntry.isPresent()) {
369 elanForwardingEntriesHandler.updateElanInterfaceForwardingTablesList(elanInstanceName, interfaceName, existingMacEntry.get().getInterface(), existingMacEntry.get());
371 elanForwardingEntriesHandler.addElanInterfaceForwardingTableList(elanInstance, interfaceName, physAddress);
373 if(interfaceInfo != null && isOperational(interfaceInfo)) {
374 logger.debug("Installing Static Mac-Entry on the Elan Interface:{} with MacAddress:{}", interfaceInfo, physAddress.getValue());
375 ElanUtils.setupMacFlows(elanInstance, interfaceInfo, ElanConstants.STATIC_MAC_TIMEOUT, physAddress.getValue());
381 private Map<BigInteger, List<String>> readFePortsDbForElan(String elanName) {
382 ElanDpnInterfacesList elanDpnInterfacesList = ElanUtils.getElanDpnInterfacesList(elanName);
383 HashMap<BigInteger, List<String>> fePortsDb = Maps.newHashMap();
384 if (elanDpnInterfacesList == null) {
387 List<DpnInterfaces> dpnInterfaces = elanDpnInterfacesList.getDpnInterfaces();
388 if (dpnInterfaces == null) {
391 for (DpnInterfaces dpnInterface : dpnInterfaces) {
392 fePortsDb.put(dpnInterface.getDpId(), dpnInterface.getInterfaces());
397 protected void removeInterfaceStaticMacEntires(String elanInstanceName, String interfaceName, PhysAddress physAddress) {
398 InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
399 InstanceIdentifier<MacEntry> macId = getMacEntryOperationalDataPath(elanInstanceName, physAddress);
400 Optional<MacEntry> existingMacEntry = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, macId);
402 if(!existingMacEntry.isPresent()) {
406 MacEntry macEntry = new MacEntryBuilder().setMacAddress(physAddress).setInterface(interfaceName).setKey(new MacEntryKey(physAddress)).build();
407 elanForwardingEntriesHandler.deleteElanInterfaceForwardingEntries(ElanUtils.getElanInstanceByName(elanInstanceName), interfaceInfo, macEntry);
408 elanForwardingEntriesHandler.deleteElanInterfaceMacForwardingEntries(interfaceName, physAddress);
412 private InstanceIdentifier<MacEntry> getMacEntryOperationalDataPath(String elanName, PhysAddress physAddress) {
413 return InstanceIdentifier.builder(ElanForwardingTables.class).child(MacTable.class,
414 new MacTableKey(elanName)).child(MacEntry.class, new MacEntryKey(physAddress)).build();
417 public void installFlowsAndGroups(final ElanInstance elanInfo, final InterfaceInfo interfaceInfo) {
418 if (isOperational(interfaceInfo)) {
420 // LocalBroadcast Group creation with elan-Interfaces
421 setupElanBroadcastGroups(elanInfo, interfaceInfo);
423 setupLocalBroadcastGroups(elanInfo, interfaceInfo);
424 //Terminating Service , UnknownDMAC Table.
425 setupTerminateServiceTable(elanInfo, interfaceInfo);
426 setupUnknownDMacTable(elanInfo, interfaceInfo);
427 setupFilterEqualsTable(elanInfo, interfaceInfo);
428 // bind the Elan service to the Interface
429 bindService(elanInfo, interfaceInfo.getInterfaceName());
431 //update the remote-DPNs remoteBC group entry with Tunnels
432 setElanBCGrouponOtherDpns(elanInfo, interfaceInfo);
436 public void setupFilterEqualsTable(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
437 int ifTag = interfaceInfo.getInterfaceTag();
438 Flow flow = MDSALUtil.buildFlowNew(ElanConstants.ELAN_FILTER_EQUALS_TABLE, getFlowRef(ElanConstants.ELAN_FILTER_EQUALS_TABLE, ifTag),
439 9, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_FILTER_EQUALS.add(BigInteger.valueOf(ifTag)), getTunnelIdMatchForFilterEqualsLPortTag(ifTag), ElanUtils.getInstructionsInPortForOutGroup(interfaceInfo.getInterfaceName()));
441 mdsalManager.installFlow(interfaceInfo.getDpId(), flow);
443 Flow flowEntry = MDSALUtil.buildFlowNew(ElanConstants.ELAN_FILTER_EQUALS_TABLE, getFlowRef(ElanConstants.ELAN_FILTER_EQUALS_TABLE, 1000+ifTag),
444 10, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_FILTER_EQUALS.add(BigInteger.valueOf(ifTag)), getMatchesForFilterEqualsLPortTag(ifTag),
445 getInstructionsDrop());
447 mdsalManager.installFlow(interfaceInfo.getDpId(), flowEntry);
450 public void removeFilterEqualsTable(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
451 int ifTag = interfaceInfo.getInterfaceTag();
452 Flow flow = MDSALUtil.buildFlowNew(ElanConstants.ELAN_FILTER_EQUALS_TABLE, getFlowRef(ElanConstants.ELAN_FILTER_EQUALS_TABLE, ifTag),
453 9, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_FILTER_EQUALS.add(BigInteger.valueOf(ifTag)), getTunnelIdMatchForFilterEqualsLPortTag(ifTag), ElanUtils.getInstructionsInPortForOutGroup(interfaceInfo.getInterfaceName()));
455 mdsalManager.removeFlow(interfaceInfo.getDpId(), flow);
457 Flow flowEntity = MDSALUtil.buildFlowNew(ElanConstants.ELAN_FILTER_EQUALS_TABLE, getFlowRef(ElanConstants.ELAN_FILTER_EQUALS_TABLE, 1000+ifTag),
458 10, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_FILTER_EQUALS.add(BigInteger.valueOf(ifTag)), getMatchesForFilterEqualsLPortTag(ifTag),
459 getInstructionsDrop());
461 mdsalManager.removeFlow(interfaceInfo.getDpId(), flowEntity);
464 private List<Bucket> getRemoteBCGroupBucketInfos(ElanInstance elanInfo,
465 int bucketKeyStart, InterfaceInfo interfaceInfo) {
466 BigInteger dpnId = interfaceInfo.getDpId();
467 int elanTag = elanInfo.getElanTag().intValue();
468 int bucketId = bucketKeyStart;
469 List<Bucket> listBuckets = new ArrayList<Bucket>();
470 ElanDpnInterfacesList elanDpns = ElanUtils.getElanDpnInterfacesList(elanInfo.getElanInstanceName());
471 if(elanDpns != null) {
472 List<DpnInterfaces> dpnInterfaceses = elanDpns.getDpnInterfaces();
473 for(DpnInterfaces dpnInterface : dpnInterfaceses) {
474 if(ElanUtils.isDpnPresent(dpnInterface.getDpId()) && dpnInterface.getDpId() != dpnId && dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty()) {
476 List<Action> listAction = ElanUtils.getItmEgressAction(dpnId, dpnInterface.getDpId(), (int) elanTag);
477 listBuckets.add(MDSALUtil.buildBucket(listAction, MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
479 } catch (Exception ex) {
480 logger.error( "Logical Group Interface not found between source Dpn - {}, destination Dpn - {} " ,dpnId, dpnInterface.getDpId() );
488 private List<Bucket> getRemoteBCGroupBuckets(ElanInstance elanInfo,
489 InterfaceInfo interfaceInfo, int bucketId) {
490 BigInteger dpnId = interfaceInfo.getDpId();
491 int elanTag = elanInfo.getElanTag().intValue();
492 List<Bucket> listBucketInfo = new ArrayList<Bucket>();
493 ElanDpnInterfacesList elanDpns = ElanUtils.getElanDpnInterfacesList(elanInfo.getElanInstanceName());
494 if(elanDpns != null) {
495 List<DpnInterfaces> dpnInterfaceses = elanDpns.getDpnInterfaces();
496 for(DpnInterfaces dpnInterface : dpnInterfaceses) {
497 if(ElanUtils.isDpnPresent(dpnInterface.getDpId()) && dpnInterface.getDpId() != dpnId && dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty()) {
499 List<Action> listActionInfo = ElanUtils.getItmEgressAction(dpnId, dpnInterface.getDpId(), (int) elanTag);
500 listBucketInfo.add(MDSALUtil.buildBucket(listActionInfo, 0, bucketId, 0xffffffffL, 0xffffffffL));
502 } catch (Exception ex) {
503 logger.error( "Logical Group Interface not found between source Dpn - {}, destination Dpn - {} " ,dpnId, dpnInterface.getDpId() );
508 return listBucketInfo;
511 private void setElanBCGrouponOtherDpns(ElanInstance elanInfo,
512 InterfaceInfo interfaceInfo) {
513 BigInteger dpnId = interfaceInfo.getDpId();
514 int elanTag = elanInfo.getElanTag().intValue();
515 long groupId = ElanUtils.getElanRemoteBCGID(elanTag);
516 List<Bucket> listBucket = new ArrayList<Bucket>();
518 ElanDpnInterfacesList elanDpns = ElanUtils.getElanDpnInterfacesList(elanInfo.getElanInstanceName());
519 if(elanDpns != null) {
520 List<DpnInterfaces> dpnInterfaceses = elanDpns.getDpnInterfaces();
521 for(DpnInterfaces dpnInterface : dpnInterfaceses) {
522 List<Bucket> remoteListBucketInfo = new ArrayList<Bucket>();
523 if(ElanUtils.isDpnPresent(dpnInterface.getDpId()) && !dpnInterface.getDpId().equals(dpnId) && dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty()) {
524 for(String ifName : dpnInterface.getInterfaces()) {
525 // In case if there is a InterfacePort in the cache which is not in
526 // operational state, skip processing it
527 InterfaceInfo ifInfo = interfaceManager.getInterfaceInfoFromOperationalDataStore(ifName, interfaceInfo.getInterfaceType());
528 if (!isOperational(ifInfo)) {
532 listBucket.add(MDSALUtil.buildBucket(getInterfacePortActions(ifInfo), MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
535 remoteListBucketInfo.addAll(listBucket);
536 for(DpnInterfaces otherFes : dpnInterfaceses) {
537 if (ElanUtils.isDpnPresent(otherFes.getDpId()) && otherFes.getDpId() != dpnInterface.getDpId()
538 && otherFes.getInterfaces() != null && ! otherFes.getInterfaces().isEmpty()) {
540 List<Action> remoteListActionInfo = ElanUtils.getItmEgressAction(dpnInterface.getDpId(), otherFes.getDpId(), (int) elanTag);
541 remoteListBucketInfo.add(MDSALUtil.buildBucket(remoteListActionInfo, MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT,MDSALUtil.WATCH_GROUP));
543 } catch (Exception ex) {
544 logger.error( "Logical Group Interface not found between source Dpn - {}, destination Dpn - {} " ,dpnInterface.getDpId(), otherFes.getDpId() );
549 if(remoteListBucketInfo.size() == 0) {
550 logger.debug( "No ITM is present on Dpn - {} " ,dpnInterface.getDpId());
553 Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, MDSALUtil.buildBucketLists(remoteListBucketInfo));
554 mdsalManager.syncInstallGroup(dpnInterface.getDpId(), group, ElanConstants.DELAY_TIME_IN_MILLISECOND);
560 private void updateRemoteBCGrouponDpnTunnelEvent(ElanInstance elanInfo,
561 InterfaceInfo interfaceInfo, BigInteger dstDpId) {
562 int elanTag = elanInfo.getElanTag().intValue();
563 long groupId = ElanUtils.getElanRemoteBCGID(elanTag);
564 DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanInfo.getElanInstanceName(), interfaceInfo.getDpId());
565 List<DpnInterfaces> elanDpns = ElanUtils.getInvolvedDpnsInElan(elanInfo.getElanInstanceName());
566 if(elanDpns != null) {
567 for(DpnInterfaces dpnInterface : elanDpns) {
569 List<Bucket> remoteListBucket = new ArrayList<Bucket>();
570 if(ElanUtils.isDpnPresent(dstDpId) && dpnInterface.getDpId().equals(dstDpId) && dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty()) {
571 for(String ifName : dpnInterfaces.getInterfaces()) {
572 // In case if there is a InterfacePort in the cache which is not in
573 // operational state, skip processing it
574 InterfaceInfo ifInfo = interfaceManager.getInterfaceInfoFromOperationalDataStore(ifName, interfaceInfo.getInterfaceType());
575 if (!isOperational(ifInfo)) {
579 remoteListBucket.add(MDSALUtil.buildBucket(getInterfacePortActions(ifInfo), MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
583 List<Action> remoteListActionInfo = ElanUtils.getItmEgressAction(interfaceInfo.getDpId(), dstDpId, (int) elanTag);
584 remoteListBucket.add(MDSALUtil.buildBucket(remoteListActionInfo, MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
586 } catch (Exception ex) {
587 logger.error( "Logical Group Interface not found between source Dpn - {}, destination Dpn - {} " ,dpnInterface.getDpId(), dstDpId);
590 Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, MDSALUtil.buildBucketLists(remoteListBucket));
591 mdsalManager.syncInstallGroup(interfaceInfo.getDpId(), group, ElanConstants.DELAY_TIME_IN_MILLISECOND);
600 * Returns the bucket info with the given interface as the only bucket.
602 private Bucket getLocalBCGroupBucketInfo(InterfaceInfo interfaceInfo, int bucketIdStart) {
603 return MDSALUtil.buildBucket(getInterfacePortActions(interfaceInfo), MDSALUtil.GROUP_WEIGHT, bucketIdStart, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP);
606 private List<MatchInfo> getMatchesForElanTag(Long elanTag) {
607 List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
609 mkMatches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
610 ElanUtils.getElanMetadataLabel(elanTag),
611 MetaDataUtil.METADATA_MASK_SERVICE }));
615 private List<Instruction> getInstructionsForOutGroup(
617 List<Instruction> mkInstructions = new ArrayList<Instruction>();
618 List <Action> actions = new ArrayList <Action> ();
619 actions.add(new ActionInfo(ActionType.group, new String[]{Long.toString(groupId)}).buildAction());
620 mkInstructions.add(ElanUtils.getWriteActionInstruction(actions));
621 return mkInstructions;
624 public void removeFlowsAndGroups(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
625 removeStaticELanFlows(elanInfo, interfaceInfo);
626 unbindService(elanInfo, interfaceInfo.getInterfaceName());
629 public void installMacAddressTables(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
630 String interfaceName = interfaceInfo.getInterfaceName();
631 BigInteger currentDpn = interfaceInfo.getDpId();
632 ElanInterfaceMac elanInterfaceMac = ElanUtils.getElanInterfaceMacByInterfaceName(interfaceName);
633 if(elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null) {
634 List<MacEntry> macEntries = elanInterfaceMac.getMacEntry();
635 for(MacEntry macEntry : macEntries) {
636 PhysAddress physAddress = macEntry.getMacAddress();
637 ElanUtils.setupMacFlows(elanInfo, interfaceInfo, macEntry.isIsStaticAddress() ? ElanConstants.STATIC_MAC_TIMEOUT : elanInfo.getMacTimeout(), physAddress.getValue());
639 //Programming the remoteDMACFlows
640 ElanDpnInterfacesList elanDpnInterfacesList = ElanUtils.getElanDpnInterfacesList(elanInfo.getElanInstanceName());
641 List<DpnInterfaces> dpnInterfaceLists = elanDpnInterfacesList.getDpnInterfaces();
642 for(DpnInterfaces dpnInterfaces : dpnInterfaceLists){
643 if(dpnInterfaces.getDpId().equals(interfaceInfo.getDpId())) {
646 List<String> remoteElanInterfaces = dpnInterfaces.getInterfaces();
647 for(String remoteIf : remoteElanInterfaces) {
648 ElanInterfaceMac elanIfMac = ElanUtils.getElanInterfaceMacByInterfaceName(remoteIf);
649 InterfaceInfo remoteInterface = interfaceManager.getInterfaceInfo(remoteIf);
650 if(elanIfMac == null) {
653 List<MacEntry> remoteMacEntries = elanIfMac.getMacEntry();
654 if(remoteMacEntries != null) {
655 for (MacEntry macEntry : remoteMacEntries) {
656 PhysAddress physAddress = macEntry.getMacAddress();
657 ElanUtils.setupRemoteDmacFlow(currentDpn, remoteInterface.getDpId(), remoteInterface.getInterfaceTag(), elanInfo.getElanTag(), physAddress.getValue(), elanInfo.getElanInstanceName());
665 // Install DMAC entry on dst DPN
666 public void installDMacAddressTables(ElanInstance elanInfo, InterfaceInfo interfaceInfo, BigInteger dstDpId) {
667 String interfaceName = interfaceInfo.getInterfaceName();
668 ElanInterfaceMac elanInterfaceMac = ElanUtils.getElanInterfaceMacByInterfaceName(interfaceName);
669 if(elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null) {
670 List<MacEntry> macEntries = elanInterfaceMac.getMacEntry();
671 for(MacEntry macEntry : macEntries) {
672 PhysAddress physAddress = macEntry.getMacAddress();
673 ElanUtils.setupDMacFlowonRemoteDpn(elanInfo, interfaceInfo, dstDpId, physAddress.getValue());
678 public void removeMacAddressTables(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
679 ElanInterfaceMac elanInterfaceMac = ElanUtils.getElanInterfaceMacByInterfaceName(interfaceInfo.getInterfaceName());
680 if(elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null) {
681 List<MacEntry> macEntries = elanInterfaceMac.getMacEntry();
682 for(MacEntry macEntry : macEntries) {
683 ElanUtils.deleteMacFlows(elanInfo, interfaceInfo, macEntry);
688 public void setupElanBroadcastGroups(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
689 List<Bucket> listBucket = new ArrayList<Bucket>();
691 BigInteger dpnId = interfaceInfo.getDpId();
692 long groupId = ElanUtils.getElanRemoteBCGID(elanInfo.getElanTag());
694 DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanInfo.getElanInstanceName(), dpnId);
695 for(String ifName : dpnInterfaces.getInterfaces()) {
696 // In case if there is a InterfacePort in the cache which is not in
697 // operational state, skip processing it
698 InterfaceInfo ifInfo = interfaceManager.getInterfaceInfoFromOperationalDataStore(ifName, interfaceInfo.getInterfaceType());
699 if (ifInfo == null || !isOperational(ifInfo)) {
703 listBucket.add(MDSALUtil.buildBucket(getInterfacePortActions(ifInfo), MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
706 List<Bucket> listBucketInfoRemote = getRemoteBCGroupBuckets(elanInfo, interfaceInfo, bucketId);
707 listBucket.addAll(listBucketInfoRemote);
709 Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, MDSALUtil.buildBucketLists(listBucket));
710 logger.trace("installing the localBroadCast Group:{}", group);
711 // In the case of OVS disconnected we receive null object when we query Interface Operation datastore
712 // so the size of the bucket will be zero
713 if(listBucket.size() == 0) {
714 mdsalManager.syncRemoveGroup(dpnId, group);
716 mdsalManager.syncInstallGroup(dpnId, group, ElanConstants.DELAY_TIME_IN_MILLISECOND);
720 public void setupLocalBroadcastGroups(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
721 List<Bucket> listBucket = new ArrayList<Bucket>();
723 BigInteger dpnId = interfaceInfo.getDpId();
724 long groupId = ElanUtils.getElanLocalBCGID(elanInfo.getElanTag());
726 DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanInfo.getElanInstanceName(), dpnId);
727 for(String ifName : dpnInterfaces.getInterfaces()) {
728 // In case if there is a InterfacePort in the cache which is not in
729 // operational state, skip processing it
730 InterfaceInfo ifInfo = interfaceManager.getInterfaceInfoFromOperationalDataStore(ifName, interfaceInfo.getInterfaceType());
731 if (ifInfo == null || !isOperational(ifInfo)) {
735 listBucket.add(MDSALUtil.buildBucket(getInterfacePortActions(ifInfo), MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
740 Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, MDSALUtil.buildBucketLists(listBucket));
741 logger.trace("installing the localBroadCast Group:{}", group);
742 // In the case of OVS disconnected we receive null object for the Interface Operation datastore
743 // so the size of the bucket will be zero
744 if(listBucket.size() == 0) {
745 mdsalManager.syncRemoveGroup(dpnId, group);
747 mdsalManager.syncInstallGroup(dpnId, group, ElanConstants.DELAY_TIME_IN_MILLISECOND);
751 public void removeLocalBroadcastGroup(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
752 BigInteger dpnId = interfaceInfo.getDpId();
753 long groupId = ElanUtils.getElanLocalBCGID(elanInfo.getElanTag());
754 List<Bucket> listBuckets = new ArrayList<>();
756 listBuckets.add(getLocalBCGroupBucketInfo(interfaceInfo, bucketId));
757 //listBuckets.addAll(getRemoteBCGroupBucketInfos(elanInfo, 1, interfaceInfo));
758 Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, MDSALUtil.buildBucketLists(listBuckets));
759 logger.trace("deleted the localBroadCast Group:{}", group);
760 mdsalManager.syncRemoveGroup(dpnId, group);
763 public void removeElanBroadcastGroup(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
765 List<Bucket> listBuckets = new ArrayList<>();
766 listBuckets.add(getLocalBCGroupBucketInfo(interfaceInfo, bucketId));
768 listBuckets.addAll(getRemoteBCGroupBucketInfos(elanInfo, bucketId, interfaceInfo));
769 BigInteger dpnId = interfaceInfo.getDpId();
770 long groupId = ElanUtils.getElanRemoteBCGID(elanInfo.getElanTag());
771 Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, MDSALUtil.buildBucketLists(listBuckets));
772 logger.trace("deleting the remoteBroadCast group:{}", group);
773 mdsalManager.syncRemoveGroup(dpnId, group);
776 public void setupTerminateServiceTable(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
777 long elanTag = elanInfo.getElanTag();
778 Flow flowEntity = MDSALUtil.buildFlowNew(NwConstants.INTERNAL_TUNNEL_TABLE, getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE, elanTag),
779 5, String.format("%s:%d","ITM Flow Entry ",elanTag), 0, 0, ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(elanTag)), ElanUtils.getTunnelMatchesForServiceId((int)elanTag),
780 getInstructionsForOutGroup(ElanUtils.getElanRemoteBCGID(elanTag)));
782 mdsalManager.installFlow(interfaceInfo.getDpId(), flowEntity);
785 public void setupUnknownDMacTable(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
786 long elanTag = elanInfo.getElanTag();
787 Flow flowEntity = MDSALUtil.buildFlowNew(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, getFlowRef(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, elanTag),
788 5, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_UNKNOWN_DMAC.add(BigInteger.valueOf(elanTag)), getMatchesForElanTag(elanTag),
789 getInstructionsForOutGroup(ElanUtils.getElanRemoteBCGID(elanTag)));
791 mdsalManager.installFlow(interfaceInfo.getDpId(), flowEntity);
794 private void removeStaticELanFlows(final ElanInstance elanInfo, final InterfaceInfo interfaceInfo) {
795 BigInteger dpId = interfaceInfo.getDpId();
796 long elanTag = elanInfo.getElanTag();
798 * If there are not elan ports, remove the unknown smac and default dmac
801 DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanInfo.getElanInstanceName(), dpId);
802 if(dpnInterfaces == null) {
805 List <String> elanInterfaces = dpnInterfaces.getInterfaces();
806 if (elanInterfaces == null || elanInterfaces.isEmpty()) {
808 logger.debug("deleting the elan: {} present on dpId: {}", elanInfo.getElanInstanceName(), dpId);
809 removeDefaultTermFlow(dpId, elanInfo.getElanTag());
810 removeUnknownDmacFlow(dpId, elanInfo);
811 removeElanBroadcastGroup(elanInfo, interfaceInfo);
812 removeLocalBroadcastGroup(elanInfo, interfaceInfo);
813 removeFilterEqualsTable(elanInfo, interfaceInfo);
815 setupElanBroadcastGroups(elanInfo, interfaceInfo);
816 setupLocalBroadcastGroups(elanInfo, interfaceInfo);
817 removeFilterEqualsTable(elanInfo, interfaceInfo);
821 private void removeUnknownDmacFlow(BigInteger dpId, ElanInstance elanInfo) {
822 Flow flow = getUnknownDmacFlowEntity(dpId, elanInfo);
823 mdsalManager.removeFlow(dpId, flow);
826 private void removeDefaultTermFlow(BigInteger dpId, long elanTag) {
827 ElanUtils.removeTerminatingServiceAction(dpId, (int) elanTag);
830 private void bindService(ElanInstance elanInfo, String interfaceName) {
831 // interfaceManager.bindService(interfaceName, ElanUtils.getServiceInfo(elanInfo.getElanInstanceName(), elanInfo.getElanTag(), interfaceName));
833 int priority = ElanConstants.ELAN_SERVICE_PRIORITY;
834 int instructionKey = 0;
835 List<Instruction> instructions = new ArrayList<Instruction>();
836 instructions.add(MDSALUtil.buildAndGetWriteMetadaInstruction(ElanUtils.getElanMetadataLabel(elanInfo.getElanTag()), MetaDataUtil.METADATA_MASK_SERVICE, ++instructionKey));
837 instructions.add(MDSALUtil.buildAndGetGotoTableInstruction(ElanConstants.ELAN_SMAC_TABLE, ++instructionKey));
840 ElanUtils.getBoundServices(String.format("%s.%s.%s", "vpn",elanInfo.getElanInstanceName(), interfaceName),
841 ElanConstants.ELAN_SERVICE_INDEX, priority,
842 ElanConstants.COOKIE_ELAN_INGRESS_TABLE, instructions);
843 ElanUtils.syncWrite(broker, LogicalDatastoreType.CONFIGURATION,
844 ElanUtils.buildServiceId(interfaceName, ElanConstants.ELAN_SERVICE_INDEX), serviceInfo);
847 private void unbindService(ElanInstance elanInfo, String interfaceName) {
848 ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION,
849 ElanUtils.buildServiceId(interfaceName,ElanConstants.ELAN_SERVICE_INDEX),
850 ElanUtils.DEFAULT_CALLBACK);
853 private void unbindService(ElanInstance elanInfo, String interfaceName, int vlanId) {
854 ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION,
855 ElanUtils.buildServiceId(interfaceName,ElanConstants.ELAN_SERVICE_INDEX),
856 ElanUtils.DEFAULT_CALLBACK);
859 private Flow getUnknownDmacFlowEntity(BigInteger dpId, ElanInstance elanInfo) {
860 long elanTag = elanInfo.getElanTag();
861 List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
863 mkMatches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
864 ElanUtils.getElanMetadataLabel(elanTag),
865 MetaDataUtil.METADATA_MASK_SERVICE }));
867 List<Instruction> mkInstructions = new ArrayList<Instruction>();
868 List <Action> actionsInfos = new ArrayList <Action> ();
869 actionsInfos.add(new ActionInfo(ActionType.group, new String[]{Long.toString(ElanUtils.getElanRemoteBCGID(elanTag))}, 0).buildAction());
870 mkInstructions.add(ElanUtils.getWriteActionInstruction(actionsInfos));
872 Flow flow = MDSALUtil.buildFlowNew(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, getFlowRef(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, elanTag),
873 5, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_UNKNOWN_DMAC.add(BigInteger.valueOf(elanTag)),
874 mkMatches, mkInstructions);
878 private String getFlowRef(long tableId, long elanTag) {
879 return new StringBuffer().append(tableId).append(elanTag).toString();
882 private List<Action> getInterfacePortActions(InterfaceInfo interfaceInfo) {
883 List<Action> listAction = new ArrayList<Action>();
885 listAction.add((new ActionInfo(ActionType.set_field_tunnel_id, new BigInteger[] {BigInteger.valueOf(interfaceInfo.getInterfaceTag())}, actionKey)).buildAction());
887 listAction.add((new ActionInfo(ActionType.nx_resubmit, new BigInteger[] {BigInteger.valueOf(55)}, actionKey)).buildAction());
891 private void updateElanDpnInterfacesList(String elanInstanceName, BigInteger dpId, List<String> interfaceNames) {
892 DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId)
893 .setInterfaces(interfaceNames).setKey(new DpnInterfacesKey(dpId)).build();
894 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId),
898 private List<String> createElanInterfacesList(String elanInstanceName, String interfaceName, BigInteger dpId) {
899 List<String> interfaceNames = new ArrayList<String>();
900 interfaceNames.add(interfaceName);
901 DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId)
902 .setInterfaces(interfaceNames).setKey(new DpnInterfacesKey(dpId)).build();
903 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId),
905 return interfaceNames;
908 private void createElanInterfaceTablesList(String interfaceName) {
909 InstanceIdentifier<ElanInterfaceMac> elanInterfaceMacTables = ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName);
910 Optional<ElanInterfaceMac> interfaceMacTables = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanInterfaceMacTables);
911 // Adding new Elan Interface Port to the operational DataStore without Static-Mac Entries..
912 if(!interfaceMacTables.isPresent()) {
913 ElanInterfaceMac elanInterfaceMacTable = new ElanInterfaceMacBuilder().setElanInterface(interfaceName).setKey(new ElanInterfaceMacKey(interfaceName)).build();
914 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName),
915 elanInterfaceMacTable);
919 private void createElanStateList(String elanInstanceName, String interfaceName) {
920 InstanceIdentifier<Elan> elanInstance = ElanUtils.getElanInstanceOperationalDataPath(elanInstanceName);
921 Optional<Elan> elanInterfaceLists = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanInstance);
922 // Adding new Elan Interface Port to the operational DataStore without Static-Mac Entries..
923 if(elanInterfaceLists.isPresent()) {
924 List<String> interfaceLists = elanInterfaceLists.get().getElanInterfaces();
925 if(interfaceLists == null) {
926 interfaceLists = new ArrayList<>();
928 interfaceLists.add(interfaceName);
929 Elan elanState = new ElanBuilder().setName(elanInstanceName).setElanInterfaces(interfaceLists).setKey(new ElanKey(elanInstanceName)).build();
930 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanInstanceName), elanState);
934 private boolean isOperational(InterfaceInfo interfaceInfo) {
935 return ((interfaceInfo.getOpState() == InterfaceInfo.InterfaceOpState.UP) && (interfaceInfo.getAdminState() == InterfaceInfo.InterfaceAdminState.ENABLED));
938 protected void updatedIfPrimaryAttributeChanged(ElanInterface elanInterface, boolean isUpdated) {
939 String interfaceName = elanInterface.getName();
940 InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
941 BigInteger dpId = interfaceInfo.getDpId();
942 InstanceIdentifier<ElanInterfaceMac> elanInterfaceId = ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName);
943 Optional<ElanInterfaceMac> existingElanInterface = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanInterfaceId);
944 ElanInstance elanInfo = ElanUtils.getElanInstanceByName(elanInterface.getElanInstanceName());
946 if(!existingElanInterface.isPresent()) {
950 List<MacEntry> macEntries = existingElanInterface.get().getMacEntry();
951 if(macEntries != null && !macEntries.isEmpty()) {
952 for (MacEntry macEntry : macEntries) {
954 ElanUtils.setupMacFlows(elanInfo, interfaceInfo, ElanConstants.STATIC_MAC_TIMEOUT, macEntry.getMacAddress().getValue());
956 ElanUtils.deleteMacFlows(elanInfo, interfaceInfo, macEntry);
961 InstanceIdentifier<DpnInterfaces> dpnInterfaceId = ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInterface.getElanInstanceName(), interfaceInfo.getDpId());
962 Optional<DpnInterfaces> dpnInterfaces = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, dpnInterfaceId);
963 List<String> interfaceLists = dpnInterfaces.get().getInterfaces();
966 interfaceLists.add(elanInterface.getName());
968 interfaceLists.remove(elanInterface.getName());
971 DpnInterfaces updateDpnInterfaces = new DpnInterfacesBuilder().setInterfaces(interfaceLists).setDpId(dpId).setKey(new DpnInterfacesKey(dpId)).build();
972 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, dpnInterfaceId, updateDpnInterfaces);
975 installFlowsAndGroups(elanInfo, interfaceInfo);
977 removeStaticELanFlows(elanInfo, interfaceInfo);
978 unbindService(elanInfo, interfaceName);
982 public void handleTunnelStateEvent(BigInteger srcDpId, BigInteger dstDpId) {
983 ElanDpnInterfaces dpnInterfaceLists = ElanUtils.getElanDpnInterfacesList();
984 Set<String> elanInstancesMap = new HashSet<>();
985 if(dpnInterfaceLists == null) {
988 List<ElanDpnInterfacesList> elanDpnIf = dpnInterfaceLists.getElanDpnInterfacesList();
989 for(ElanDpnInterfacesList elanDpns: elanDpnIf) {
991 String elanName = elanDpns.getElanInstanceName();
992 List<DpnInterfaces> dpnInterfaces = elanDpns.getDpnInterfaces();
993 if(dpnInterfaces == null) {
996 for (DpnInterfaces dpnIf : dpnInterfaces) {
997 if(dpnIf.getDpId().equals(srcDpId) || dpnIf.getDpId().equals(dstDpId)) {
1002 logger.debug("Elan instance:{} is present b/w srcDpn:{} and dstDpn:{}", elanName, srcDpId, dstDpId);
1003 DpnInterfaces dpnInterface = ElanUtils.getElanInterfaceInfoByElanDpn(elanName, srcDpId);
1004 Set<String> interfaceLists = new HashSet<>();
1005 ElanInstance elanInfo = ElanUtils.getElanInstanceByName(elanName);
1006 interfaceLists.addAll(dpnInterface.getInterfaces());
1007 for(String ifName : interfaceLists) {
1008 InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(ifName);
1009 if (isOperational(interfaceInfo)) {
1010 if (interfaceInfo.getDpId().equals(srcDpId) && !elanInstancesMap.contains(elanDpns.getElanInstanceName())) {
1011 elanInstancesMap.add(elanDpns.getElanInstanceName());
1012 elanInterfaceManager.updateRemoteBCGrouponDpnTunnelEvent(elanInfo, interfaceInfo, dstDpId);
1014 elanInterfaceManager.installDMacAddressTables(elanInfo, interfaceInfo, dstDpId);
1022 public void handleInterfaceUpated(InterfaceInfo interfaceInfo, ElanInstance elanInstance, boolean isStateUp) {
1023 BigInteger dpId = interfaceInfo.getDpId();
1024 String elanName = elanInstance.getElanInstanceName();
1025 String ifName = interfaceInfo.getInterfaceName();
1026 logger.trace("Handling interface update event for interface with info {} , state {}", interfaceInfo, isStateUp);
1029 DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanName, dpId);
1030 if(dpnInterfaces == null) {
1031 createElanInterfacesList(elanName, interfaceInfo.getInterfaceName(), dpId);
1033 List<String> dpnElanInterfaces = dpnInterfaces.getInterfaces();
1034 dpnElanInterfaces.add(interfaceInfo.getInterfaceName());
1035 DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId)
1036 .setInterfaces(dpnElanInterfaces).setKey(new DpnInterfacesKey(dpId)).build();
1037 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanName, interfaceInfo.getDpId()), dpnInterface);
1040 logger.trace("ElanInterface Service is installed for interface:{}", ifName);
1041 elanInterfaceManager.installFlowsAndGroups(elanInstance, interfaceInfo);
1042 elanInterfaceManager.installMacAddressTables(elanInstance, interfaceInfo);
1045 DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanName, dpId);
1046 if(dpnInterfaces != null) {
1047 List<String> dpnElanInterfaces = dpnInterfaces.getInterfaces();
1048 dpnElanInterfaces.remove(interfaceInfo.getInterfaceName());
1049 DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId)
1050 .setInterfaces(dpnElanInterfaces).setKey(new DpnInterfacesKey(dpId)).build();
1051 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanName, interfaceInfo.getDpId()), dpnInterface);
1053 logger.trace("ElanInterface Service is removed for the interface:{}", ifName);
1054 elanInterfaceManager.removeMacAddressTables(elanInstance, interfaceInfo);
1055 elanInterfaceManager.removeFlowsAndGroups(elanInstance, interfaceInfo);
1059 private List<MatchInfo> getMatchesForFilterEqualsLPortTag(int LportTag) {
1060 List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
1061 // Matching metadata
1062 mkMatches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
1063 MetaDataUtil.getLportTagMetaData(LportTag),
1064 MetaDataUtil.METADATA_MASK_LPORT_TAG }));
1065 mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[] {BigInteger.valueOf(LportTag)}));
1070 private List<MatchInfo> getTunnelIdMatchForFilterEqualsLPortTag(int LportTag) {
1071 List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
1072 // Matching metadata
1073 mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[] {
1074 BigInteger.valueOf(LportTag)}));
1080 private List<Instruction> getInstructionsDrop() {
1081 List<Instruction> mkInstructions = new ArrayList<Instruction>();
1082 List <Action> actionsInfos = new ArrayList <Action> ();
1083 actionsInfos.add(new ActionInfo(ActionType.drop_action, new String[]{}).buildAction());
1084 mkInstructions.add(ElanUtils.getWriteActionInstruction(actionsInfos));
1085 return mkInstructions;