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.itm.globals.ITMConstants;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.Bucket;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.services.info.BoundServices;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
29 import org.opendaylight.vpnservice.mdsalutil.*;
30 import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.ElanDpnInterfaces;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.ElanForwardingTables;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.ElanInterfaces;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan._interface.forwarding.entries.ElanInterfaceMac;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan._interface.forwarding.entries.ElanInterfaceMacBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan._interface.forwarding.entries.ElanInterfaceMacKey;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesList;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfaces;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfacesBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfacesKey;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.forwarding.tables.MacTable;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.forwarding.tables.MacTableKey;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstance;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstanceBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.interfaces.ElanInterface;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.state.Elan;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.state.ElanBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.state.ElanKey;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntry;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntryBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntryKey;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.OdlInterfaceRpcService;
56 import org.opendaylight.yangtools.concepts.ListenerRegistration;
57 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
58 import org.slf4j.Logger;
59 import org.slf4j.LoggerFactory;
61 import java.math.BigInteger;
63 import java.util.concurrent.ConcurrentHashMap;
64 import java.util.concurrent.ConcurrentLinkedQueue;
67 public class ElanInterfaceManager extends AbstractDataChangeListener<ElanInterface> implements AutoCloseable {
69 private static ElanInterfaceManager elanInterfaceManager = new ElanInterfaceManager();
70 private ListenerRegistration<DataChangeListener> elanInterfaceListenerRegistration;
71 private ListenerRegistration<DataChangeListener> itmInterfaceListenerRegistration;
72 private OdlInterfaceRpcService interfaceManagerRpcService;
73 private DataBroker broker;
74 private IMdsalApiManager mdsalManager;
75 private IInterfaceManager interfaceManager;
76 private IdManagerService idManager;
78 private ElanForwardingEntriesHandler elanForwardingEntriesHandler;
79 private Map<String, ConcurrentLinkedQueue<ElanInterface>> unProcessedElanInterfaces =
80 new ConcurrentHashMap<String, ConcurrentLinkedQueue<ElanInterface>> ();
82 private static final Logger logger = LoggerFactory.getLogger(ElanInterfaceManager.class);
84 public ElanInterfaceManager() {
85 super(ElanInterface.class);
88 public static ElanInterfaceManager getElanInterfaceManager() {
89 return elanInterfaceManager;
92 public void setMdSalApiManager(IMdsalApiManager mdsalManager) {
93 this.mdsalManager = mdsalManager;
96 public void setInterfaceManagerRpcService(OdlInterfaceRpcService ifManager) {
97 this.interfaceManagerRpcService = ifManager;
100 public void setElanForwardingEntriesHandler(ElanForwardingEntriesHandler elanForwardingEntriesHandler) {
101 this.elanForwardingEntriesHandler = elanForwardingEntriesHandler;
104 public void setInterfaceManager(IInterfaceManager interfaceManager) {
105 this.interfaceManager = interfaceManager;
108 public void setDataBroker(DataBroker broker) {
109 this.broker = broker;
113 public void close() throws Exception {
114 if (elanInterfaceListenerRegistration != null) {
116 elanInterfaceListenerRegistration.close();
117 } catch (final Exception e) {
118 logger.error("Error when cleaning up DataChangeListener.", e);
120 elanInterfaceListenerRegistration = null;
124 public void registerListener() {
126 elanInterfaceListenerRegistration = broker.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
127 getElanInterfaceWildcardPath(), ElanInterfaceManager.this, DataChangeScope.SUBTREE);
128 } catch (final Exception e) {
129 logger.error("ELAN Interface DataChange listener registration failed !", e);
130 throw new IllegalStateException("ELAN Interface registration Listener failed.", e);
134 private InstanceIdentifier<?> getElanInterfaceWildcardPath() {
135 return InstanceIdentifier.create(ElanInterfaces.class).child(ElanInterface.class);
138 public void setIdManager(IdManagerService idManager) {
139 this.idManager = idManager;
143 protected void remove(InstanceIdentifier<ElanInterface> identifier, ElanInterface del) {
144 String interfaceName = del.getName();
145 ElanInstance elanInfo = ElanUtils.getElanInstanceByName(del.getElanInstanceName());
146 removeElanInterface(elanInfo, interfaceName);
149 public void removeElanService(ElanInterface del, int vlanId) {
150 ElanInstance elanInstance = ElanUtils.getElanInstanceByName(del.getElanInstanceName());
151 String interfaceName = del.getName();
152 InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfoFromOperationalDataStore(interfaceName, InterfaceType.VLAN_INTERFACE);
153 removeElanInterface(elanInstance, interfaceInfo);
154 unbindService(elanInstance, interfaceName, vlanId);
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 List<DpnInterfaces> elanDpns = ElanUtils.getInvolvedDpnsInElan(elanInfo.getElanInstanceName());
565 if(elanDpns != null) {
566 for(DpnInterfaces dpnInterface : elanDpns) {
568 List<Bucket> remoteListBucket = new ArrayList<Bucket>();
569 if(ElanUtils.isDpnPresent(dstDpId) && dpnInterface.getDpId().equals(dstDpId) && dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty()) {
571 List<Action> remoteListActionInfo = ElanUtils.getItmEgressAction(interfaceInfo.getDpId(), dstDpId, (int) elanTag);
572 remoteListBucket.add(MDSALUtil.buildBucket(remoteListActionInfo, MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
574 } catch (Exception ex) {
575 logger.error( "Logical Group Interface not found between source Dpn - {}, destination Dpn - {} " ,dpnInterface.getDpId(), dstDpId);
578 List<Action> remoteListActionInfo = new ArrayList<Action>();
579 remoteListActionInfo.add(new ActionInfo(ActionType.group, new String[] {String.valueOf(ElanUtils.getElanLocalBCGID(elanTag))}).buildAction());
580 remoteListBucket.add(MDSALUtil.buildBucket(remoteListActionInfo, MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
581 Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, MDSALUtil.buildBucketLists(remoteListBucket));
582 mdsalManager.syncInstallGroup(interfaceInfo.getDpId(), group, ElanConstants.DELAY_TIME_IN_MILLISECOND);
591 * Returns the bucket info with the given interface as the only bucket.
593 private Bucket getLocalBCGroupBucketInfo(InterfaceInfo interfaceInfo, int bucketIdStart) {
594 return MDSALUtil.buildBucket(getInterfacePortActions(interfaceInfo), MDSALUtil.GROUP_WEIGHT, bucketIdStart, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP);
597 private List<MatchInfo> getMatchesForElanTag(Long elanTag) {
598 List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
600 mkMatches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
601 ElanUtils.getElanMetadataLabel(elanTag),
602 MetaDataUtil.METADATA_MASK_SERVICE }));
606 private List<Instruction> getInstructionsForOutGroup(
608 List<Instruction> mkInstructions = new ArrayList<Instruction>();
609 List <Action> actions = new ArrayList <Action> ();
610 actions.add(new ActionInfo(ActionType.group, new String[]{Long.toString(groupId)}).buildAction());
611 mkInstructions.add(ElanUtils.getWriteActionInstruction(actions));
612 return mkInstructions;
615 public void removeFlowsAndGroups(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
616 removeStaticELanFlows(elanInfo, interfaceInfo);
617 unbindService(elanInfo, interfaceInfo.getInterfaceName());
620 public void installMacAddressTables(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
621 String interfaceName = interfaceInfo.getInterfaceName();
622 BigInteger currentDpn = interfaceInfo.getDpId();
623 ElanInterfaceMac elanInterfaceMac = ElanUtils.getElanInterfaceMacByInterfaceName(interfaceName);
624 if(elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null) {
625 List<MacEntry> macEntries = elanInterfaceMac.getMacEntry();
626 for(MacEntry macEntry : macEntries) {
627 PhysAddress physAddress = macEntry.getMacAddress();
628 ElanUtils.setupMacFlows(elanInfo, interfaceInfo, macEntry.isIsStaticAddress() ? ElanConstants.STATIC_MAC_TIMEOUT : elanInfo.getMacTimeout(), physAddress.getValue());
630 //Programming the remoteDMACFlows
631 ElanDpnInterfacesList elanDpnInterfacesList = ElanUtils.getElanDpnInterfacesList(elanInfo.getElanInstanceName());
632 List<DpnInterfaces> dpnInterfaceLists = elanDpnInterfacesList.getDpnInterfaces();
633 for(DpnInterfaces dpnInterfaces : dpnInterfaceLists){
634 if(dpnInterfaces.getDpId().equals(interfaceInfo.getDpId())) {
637 List<String> remoteElanInterfaces = dpnInterfaces.getInterfaces();
638 for(String remoteIf : remoteElanInterfaces) {
639 ElanInterfaceMac elanIfMac = ElanUtils.getElanInterfaceMacByInterfaceName(remoteIf);
640 InterfaceInfo remoteInterface = interfaceManager.getInterfaceInfo(remoteIf);
641 if(elanIfMac == null) {
644 List<MacEntry> remoteMacEntries = elanIfMac.getMacEntry();
645 if(remoteMacEntries != null) {
646 for (MacEntry macEntry : remoteMacEntries) {
647 PhysAddress physAddress = macEntry.getMacAddress();
648 ElanUtils.setupRemoteDmacFlow(currentDpn, remoteInterface.getDpId(), remoteInterface.getInterfaceTag(), elanInfo.getElanTag(), physAddress.getValue(), elanInfo.getElanInstanceName());
656 // Install DMAC entry on dst DPN
657 public void installDMacAddressTables(ElanInstance elanInfo, InterfaceInfo interfaceInfo, BigInteger dstDpId) {
658 String interfaceName = interfaceInfo.getInterfaceName();
659 ElanInterfaceMac elanInterfaceMac = ElanUtils.getElanInterfaceMacByInterfaceName(interfaceName);
660 if(elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null) {
661 List<MacEntry> macEntries = elanInterfaceMac.getMacEntry();
662 for(MacEntry macEntry : macEntries) {
663 PhysAddress physAddress = macEntry.getMacAddress();
664 ElanUtils.setupDMacFlowonRemoteDpn(elanInfo, interfaceInfo, dstDpId, physAddress.getValue());
669 public void removeMacAddressTables(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
670 ElanInterfaceMac elanInterfaceMac = ElanUtils.getElanInterfaceMacByInterfaceName(interfaceInfo.getInterfaceName());
671 if(elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null) {
672 List<MacEntry> macEntries = elanInterfaceMac.getMacEntry();
673 for(MacEntry macEntry : macEntries) {
674 ElanUtils.deleteMacFlows(elanInfo, interfaceInfo, macEntry);
679 public void setupElanBroadcastGroups(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
680 List<Bucket> listBucket = new ArrayList<Bucket>();
682 BigInteger dpnId = interfaceInfo.getDpId();
683 long groupId = ElanUtils.getElanRemoteBCGID(elanInfo.getElanTag());
685 DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanInfo.getElanInstanceName(), dpnId);
686 for(String ifName : dpnInterfaces.getInterfaces()) {
687 // In case if there is a InterfacePort in the cache which is not in
688 // operational state, skip processing it
689 InterfaceInfo ifInfo = interfaceManager.getInterfaceInfoFromOperationalDataStore(ifName, interfaceInfo.getInterfaceType());
690 if (!isOperational(ifInfo)) {
694 listBucket.add(MDSALUtil.buildBucket(getInterfacePortActions(ifInfo), MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
697 List<Bucket> listBucketInfoRemote = getRemoteBCGroupBuckets(elanInfo, interfaceInfo, bucketId);
698 listBucket.addAll(listBucketInfoRemote);
700 Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, MDSALUtil.buildBucketLists(listBucket));
701 logger.trace("installing the localBroadCast Group:{}", group);
702 mdsalManager.syncInstallGroup(dpnId, group, ElanConstants.DELAY_TIME_IN_MILLISECOND);
705 public void setupLocalBroadcastGroups(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
706 List<Bucket> listBucket = new ArrayList<Bucket>();
708 BigInteger dpnId = interfaceInfo.getDpId();
709 long groupId = ElanUtils.getElanLocalBCGID(elanInfo.getElanTag());
711 DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanInfo.getElanInstanceName(), dpnId);
712 for(String ifName : dpnInterfaces.getInterfaces()) {
713 // In case if there is a InterfacePort in the cache which is not in
714 // operational state, skip processing it
715 InterfaceInfo ifInfo = interfaceManager.getInterfaceInfoFromOperationalDataStore(ifName, interfaceInfo.getInterfaceType());
716 if (!isOperational(ifInfo)) {
720 listBucket.add(MDSALUtil.buildBucket(getInterfacePortActions(ifInfo), MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
724 Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, MDSALUtil.buildBucketLists(listBucket));
725 logger.trace("installing the localBroadCast Group:{}", group);
726 mdsalManager.syncInstallGroup(dpnId, group, ElanConstants.DELAY_TIME_IN_MILLISECOND);
729 public void removeLocalBroadcastGroup(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
730 BigInteger dpnId = interfaceInfo.getDpId();
731 long groupId = ElanUtils.getElanLocalBCGID(elanInfo.getElanTag());
732 List<Bucket> listBuckets = new ArrayList<>();
734 listBuckets.add(getLocalBCGroupBucketInfo(interfaceInfo, bucketId));
735 //listBuckets.addAll(getRemoteBCGroupBucketInfos(elanInfo, 1, interfaceInfo));
736 Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, MDSALUtil.buildBucketLists(listBuckets));
737 logger.trace("deleted the localBroadCast Group:{}", group);
738 mdsalManager.syncRemoveGroup(dpnId, group);
741 public void removeElanBroadcastGroup(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
743 List<Bucket> listBuckets = new ArrayList<>();
744 listBuckets.add(getLocalBCGroupBucketInfo(interfaceInfo, bucketId));
746 listBuckets.addAll(getRemoteBCGroupBucketInfos(elanInfo, bucketId, interfaceInfo));
747 BigInteger dpnId = interfaceInfo.getDpId();
748 long groupId = ElanUtils.getElanRemoteBCGID(elanInfo.getElanTag());
749 Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, MDSALUtil.buildBucketLists(listBuckets));
750 logger.trace("deleting the remoteBroadCast group:{}", group);
751 mdsalManager.syncRemoveGroup(dpnId, group);
754 public void setupTerminateServiceTable(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
755 long elanTag = elanInfo.getElanTag();
756 Flow flowEntity = MDSALUtil.buildFlowNew(ITMConstants.TERMINATING_SERVICE_TABLE, getFlowRef(ITMConstants.TERMINATING_SERVICE_TABLE, elanTag),
757 5, String.format("%s:%d","ITM Flow Entry ",elanTag), 0, 0, ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(elanTag)), ElanUtils.getTunnelMatchesForServiceId((int)elanTag),
758 getInstructionsForOutGroup(ElanUtils.getElanRemoteBCGID(elanTag)));
760 mdsalManager.installFlow(interfaceInfo.getDpId(), flowEntity);
763 public void setupUnknownDMacTable(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
764 long elanTag = elanInfo.getElanTag();
765 Flow flowEntity = MDSALUtil.buildFlowNew(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, getFlowRef(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, elanTag),
766 5, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_UNKNOWN_DMAC.add(BigInteger.valueOf(elanTag)), getMatchesForElanTag(elanTag),
767 getInstructionsForOutGroup(ElanUtils.getElanRemoteBCGID(elanTag)));
769 mdsalManager.installFlow(interfaceInfo.getDpId(), flowEntity);
772 private void removeStaticELanFlows(final ElanInstance elanInfo, final InterfaceInfo interfaceInfo) {
773 BigInteger dpId = interfaceInfo.getDpId();
774 long elanTag = elanInfo.getElanTag();
776 * If there are not elan ports, remove the unknown smac and default dmac
779 DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanInfo.getElanInstanceName(), dpId);
780 if(dpnInterfaces == null) {
783 List <String> elanInterfaces = dpnInterfaces.getInterfaces();
784 if (elanInterfaces == null || elanInterfaces.isEmpty()) {
786 logger.debug("deleting the elan: {} present on dpId: {}", elanInfo.getElanInstanceName(), dpId);
787 removeDefaultTermFlow(dpId, elanInfo.getElanTag());
788 removeUnknownDmacFlow(dpId, elanInfo);
789 removeElanBroadcastGroup(elanInfo, interfaceInfo);
790 removeLocalBroadcastGroup(elanInfo, interfaceInfo);
791 removeFilterEqualsTable(elanInfo, interfaceInfo);
793 setupElanBroadcastGroups(elanInfo, interfaceInfo);
794 removeFilterEqualsTable(elanInfo, interfaceInfo);
798 private void removeUnknownDmacFlow(BigInteger dpId, ElanInstance elanInfo) {
799 Flow flow = getUnknownDmacFlowEntity(dpId, elanInfo);
800 mdsalManager.removeFlow(dpId, flow);
803 private void removeDefaultTermFlow(BigInteger dpId, long elanTag) {
804 ElanUtils.removeTerminatingServiceAction(dpId, (int) elanTag);
807 private void bindService(ElanInstance elanInfo, String interfaceName) {
808 // interfaceManager.bindService(interfaceName, ElanUtils.getServiceInfo(elanInfo.getElanInstanceName(), elanInfo.getElanTag(), interfaceName));
810 int priority = ElanConstants.ELAN_SERVICE_PRIORITY;
811 int instructionKey = 0;
812 List<Instruction> instructions = new ArrayList<Instruction>();
813 instructions.add(MDSALUtil.buildAndGetWriteMetadaInstruction(ElanUtils.getElanMetadataLabel(elanInfo.getElanTag()), MetaDataUtil.METADATA_MASK_SERVICE, ++instructionKey));
814 instructions.add(MDSALUtil.buildAndGetGotoTableInstruction(ElanConstants.ELAN_SMAC_TABLE, ++instructionKey));
817 ElanUtils.getBoundServices(String.format("%s.%s.%s", "vpn",elanInfo.getElanInstanceName(), interfaceName),
818 ElanConstants.ELAN_SERVICE_INDEX, priority,
819 ElanConstants.COOKIE_ELAN_INGRESS_TABLE, instructions);
820 ElanUtils.syncWrite(broker, LogicalDatastoreType.CONFIGURATION,
821 ElanUtils.buildServiceId(interfaceName, ElanConstants.ELAN_SERVICE_INDEX), serviceInfo);
824 private void unbindService(ElanInstance elanInfo, String interfaceName) {
825 ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION,
826 ElanUtils.buildServiceId(interfaceName,ElanConstants.ELAN_SERVICE_INDEX),
827 ElanUtils.DEFAULT_CALLBACK);
830 private void unbindService(ElanInstance elanInfo, String interfaceName, int vlanId) {
831 ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION,
832 ElanUtils.buildServiceId(interfaceName,ElanConstants.ELAN_SERVICE_INDEX),
833 ElanUtils.DEFAULT_CALLBACK);
836 private Flow getUnknownDmacFlowEntity(BigInteger dpId, ElanInstance elanInfo) {
837 long elanTag = elanInfo.getElanTag();
838 List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
840 mkMatches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
841 ElanUtils.getElanMetadataLabel(elanTag),
842 MetaDataUtil.METADATA_MASK_SERVICE }));
844 List<Instruction> mkInstructions = new ArrayList<Instruction>();
845 List <Action> actionsInfos = new ArrayList <Action> ();
846 actionsInfos.add(new ActionInfo(ActionType.group, new String[]{Long.toString(ElanUtils.getElanRemoteBCGID(elanTag))}, 0).buildAction());
847 mkInstructions.add(ElanUtils.getWriteActionInstruction(actionsInfos));
849 Flow flow = MDSALUtil.buildFlowNew(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, getFlowRef(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, elanTag),
850 5, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_UNKNOWN_DMAC.add(BigInteger.valueOf(elanTag)),
851 mkMatches, mkInstructions);
855 private String getFlowRef(long tableId, long elanTag) {
856 return new StringBuffer().append(tableId).append(elanTag).toString();
859 private List<Action> getInterfacePortActions(InterfaceInfo interfaceInfo) {
860 List<Action> listAction = new ArrayList<Action>();
862 listAction.add((new ActionInfo(ActionType.set_field_tunnel_id, new BigInteger[] {BigInteger.valueOf(interfaceInfo.getInterfaceTag())}, actionKey)).buildAction());
864 listAction.add((new ActionInfo(ActionType.nx_resubmit, new BigInteger[] {BigInteger.valueOf(55)}, actionKey)).buildAction());
868 private void updateElanDpnInterfacesList(String elanInstanceName, BigInteger dpId, List<String> interfaceNames) {
869 DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId)
870 .setInterfaces(interfaceNames).setKey(new DpnInterfacesKey(dpId)).build();
871 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId),
875 private List<String> createElanInterfacesList(String elanInstanceName, String interfaceName, BigInteger dpId) {
876 List<String> interfaceNames = new ArrayList<String>();
877 interfaceNames.add(interfaceName);
878 DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId)
879 .setInterfaces(interfaceNames).setKey(new DpnInterfacesKey(dpId)).build();
880 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId),
882 return interfaceNames;
885 private void createElanInterfaceTablesList(String interfaceName) {
886 InstanceIdentifier<ElanInterfaceMac> elanInterfaceMacTables = ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName);
887 Optional<ElanInterfaceMac> interfaceMacTables = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanInterfaceMacTables);
888 // Adding new Elan Interface Port to the operational DataStore without Static-Mac Entries..
889 if(!interfaceMacTables.isPresent()) {
890 ElanInterfaceMac elanInterfaceMacTable = new ElanInterfaceMacBuilder().setElanInterface(interfaceName).setKey(new ElanInterfaceMacKey(interfaceName)).build();
891 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName),
892 elanInterfaceMacTable);
896 private void createElanStateList(String elanInstanceName, String interfaceName) {
897 InstanceIdentifier<Elan> elanInstance = ElanUtils.getElanInstanceOperationalDataPath(elanInstanceName);
898 Optional<Elan> elanInterfaceLists = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanInstance);
899 // Adding new Elan Interface Port to the operational DataStore without Static-Mac Entries..
900 if(elanInterfaceLists.isPresent()) {
901 List<String> interfaceLists = elanInterfaceLists.get().getElanInterfaces();
902 if(interfaceLists == null) {
903 interfaceLists = new ArrayList<>();
905 interfaceLists.add(interfaceName);
906 Elan elanState = new ElanBuilder().setName(elanInstanceName).setElanInterfaces(interfaceLists).setKey(new ElanKey(elanInstanceName)).build();
907 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanInstanceName), elanState);
911 private boolean isOperational(InterfaceInfo interfaceInfo) {
912 return ((interfaceInfo.getOpState() == InterfaceInfo.InterfaceOpState.UP) && (interfaceInfo.getAdminState() == InterfaceInfo.InterfaceAdminState.ENABLED));
915 protected void updatedIfPrimaryAttributeChanged(ElanInterface elanInterface, boolean isUpdated) {
916 String interfaceName = elanInterface.getName();
917 InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
918 BigInteger dpId = interfaceInfo.getDpId();
919 InstanceIdentifier<ElanInterfaceMac> elanInterfaceId = ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName);
920 Optional<ElanInterfaceMac> existingElanInterface = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanInterfaceId);
921 ElanInstance elanInfo = ElanUtils.getElanInstanceByName(elanInterface.getElanInstanceName());
923 if(!existingElanInterface.isPresent()) {
927 List<MacEntry> macEntries = existingElanInterface.get().getMacEntry();
928 if(macEntries != null && !macEntries.isEmpty()) {
929 for (MacEntry macEntry : macEntries) {
931 ElanUtils.setupMacFlows(elanInfo, interfaceInfo, ElanConstants.STATIC_MAC_TIMEOUT, macEntry.getMacAddress().getValue());
933 ElanUtils.deleteMacFlows(elanInfo, interfaceInfo, macEntry);
938 InstanceIdentifier<DpnInterfaces> dpnInterfaceId = ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInterface.getElanInstanceName(), interfaceInfo.getDpId());
939 Optional<DpnInterfaces> dpnInterfaces = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, dpnInterfaceId);
940 List<String> interfaceLists = dpnInterfaces.get().getInterfaces();
943 interfaceLists.add(elanInterface.getName());
945 interfaceLists.remove(elanInterface.getName());
948 DpnInterfaces updateDpnInterfaces = new DpnInterfacesBuilder().setInterfaces(interfaceLists).setDpId(dpId).setKey(new DpnInterfacesKey(dpId)).build();
949 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, dpnInterfaceId, updateDpnInterfaces);
952 installFlowsAndGroups(elanInfo, interfaceInfo);
954 removeStaticELanFlows(elanInfo, interfaceInfo);
955 unbindService(elanInfo, interfaceName);
959 public void handleTunnelStateEvent(BigInteger srcDpId, BigInteger dstDpId) {
960 ElanDpnInterfaces dpnInterfaceLists = ElanUtils.getElanDpnInterfacesList();
961 Set<String> elanInstancesMap = new HashSet<>();
962 if(dpnInterfaceLists == null) {
965 List<ElanDpnInterfacesList> elanDpnIf = dpnInterfaceLists.getElanDpnInterfacesList();
966 for(ElanDpnInterfacesList elanDpns: elanDpnIf) {
968 String elanName = elanDpns.getElanInstanceName();
969 List<DpnInterfaces> dpnInterfaces = elanDpns.getDpnInterfaces();
970 if(dpnInterfaces == null) {
973 for (DpnInterfaces dpnIf : dpnInterfaces) {
974 if(dpnIf.getDpId().equals(srcDpId) || dpnIf.getDpId().equals(dstDpId)) {
979 logger.debug("Elan instance:{} is present b/w srcDpn:{} and dstDpn:{}", elanName, srcDpId, dstDpId);
980 DpnInterfaces dpnInterface = ElanUtils.getElanInterfaceInfoByElanDpn(elanName, srcDpId);
981 Set<String> interfaceLists = new HashSet<>();
982 ElanInstance elanInfo = ElanUtils.getElanInstanceByName(elanName);
983 interfaceLists.addAll(dpnInterface.getInterfaces());
984 for(String ifName : interfaceLists) {
985 InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(ifName);
986 if (isOperational(interfaceInfo)) {
987 if (interfaceInfo.getDpId().equals(srcDpId) && !elanInstancesMap.contains(elanDpns.getElanInstanceName())) {
988 elanInstancesMap.add(elanDpns.getElanInstanceName());
989 elanInterfaceManager.updateRemoteBCGrouponDpnTunnelEvent(elanInfo, interfaceInfo, dstDpId);
991 elanInterfaceManager.installDMacAddressTables(elanInfo, interfaceInfo, dstDpId);
999 public void handleInterfaceUpated(InterfaceInfo interfaceInfo, ElanInstance elanInstance, boolean isStateUp) {
1000 BigInteger dpId = interfaceInfo.getDpId();
1001 String elanName = elanInstance.getElanInstanceName();
1002 String ifName = interfaceInfo.getInterfaceName();
1003 logger.trace("Handling interface update event for interface with info {} , state {}", interfaceInfo, isStateUp);
1006 DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanName, dpId);
1007 if(dpnInterfaces == null) {
1008 createElanInterfacesList(elanName, interfaceInfo.getInterfaceName(), dpId);
1010 List<String> dpnElanInterfaces = dpnInterfaces.getInterfaces();
1011 dpnElanInterfaces.add(interfaceInfo.getInterfaceName());
1012 DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId)
1013 .setInterfaces(dpnElanInterfaces).setKey(new DpnInterfacesKey(dpId)).build();
1014 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanName, interfaceInfo.getDpId()), dpnInterface);
1017 logger.trace("ElanInterface Service is installed for interface:{}", ifName);
1018 elanInterfaceManager.installFlowsAndGroups(elanInstance, interfaceInfo);
1019 elanInterfaceManager.installMacAddressTables(elanInstance, interfaceInfo);
1022 DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanName, dpId);
1023 if(dpnInterfaces != null) {
1024 List<String> dpnElanInterfaces = dpnInterfaces.getInterfaces();
1025 dpnElanInterfaces.remove(interfaceInfo.getInterfaceName());
1026 DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId)
1027 .setInterfaces(dpnElanInterfaces).setKey(new DpnInterfacesKey(dpId)).build();
1028 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanName, interfaceInfo.getDpId()), dpnInterface);
1030 logger.trace("ElanInterface Service is removed for the interface:{}", ifName);
1031 elanInterfaceManager.removeMacAddressTables(elanInstance, interfaceInfo);
1032 elanInterfaceManager.removeFlowsAndGroups(elanInstance, interfaceInfo);
1036 private List<MatchInfo> getMatchesForFilterEqualsLPortTag(int LportTag) {
1037 List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
1038 // Matching metadata
1039 mkMatches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
1040 MetaDataUtil.getLportTagMetaData(LportTag),
1041 MetaDataUtil.METADATA_MASK_LPORT_TAG }));
1042 mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[] {BigInteger.valueOf(LportTag)}));
1047 private List<MatchInfo> getTunnelIdMatchForFilterEqualsLPortTag(int LportTag) {
1048 List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
1049 // Matching metadata
1050 mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[] {
1051 BigInteger.valueOf(LportTag)}));
1057 private List<Instruction> getInstructionsDrop() {
1058 List<Instruction> mkInstructions = new ArrayList<Instruction>();
1059 List <Action> actionsInfos = new ArrayList <Action> ();
1060 actionsInfos.add(new ActionInfo(ActionType.drop_action, new String[]{}).buildAction());
1061 mkInstructions.add(ElanUtils.getWriteActionInstruction(actionsInfos));
1062 return mkInstructions;