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 java.math.BigInteger;
11 import java.util.ArrayList;
12 import java.util.HashSet;
13 import java.util.List;
15 import java.util.Queue;
17 import java.util.concurrent.ConcurrentHashMap;
18 import java.util.concurrent.ConcurrentLinkedQueue;
19 import java.util.concurrent.ConcurrentMap;
21 import com.google.common.base.Optional;
22 import com.google.common.collect.Maps;
24 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
25 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
26 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
27 import org.opendaylight.elanmanager.utils.ElanL2GwCacheUtils;
28 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
29 import org.opendaylight.vpnservice.elan.l2gw.utils.ElanL2GatewayMulticastUtils;
30 import org.opendaylight.vpnservice.elan.l2gw.utils.ElanL2GatewayUtils;
31 import org.opendaylight.vpnservice.elan.utils.ElanConstants;
32 import org.opendaylight.vpnservice.elan.utils.ElanUtils;
33 import org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo;
34 import org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo.InterfaceType;
35 import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
36 import org.opendaylight.vpnservice.itm.api.IITMProvider;
37 import org.opendaylight.vpnservice.itm.globals.ITMConstants;
38 import org.opendaylight.vpnservice.mdsalutil.AbstractDataChangeListener;
39 import org.opendaylight.vpnservice.mdsalutil.ActionInfo;
40 import org.opendaylight.vpnservice.mdsalutil.ActionType;
41 import org.opendaylight.vpnservice.mdsalutil.BucketInfo;
42 import org.opendaylight.vpnservice.mdsalutil.FlowEntity;
43 import org.opendaylight.vpnservice.mdsalutil.GroupEntity;
44 import org.opendaylight.vpnservice.mdsalutil.InstructionInfo;
45 import org.opendaylight.vpnservice.mdsalutil.InstructionType;
46 import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
47 import org.opendaylight.vpnservice.mdsalutil.MatchFieldType;
48 import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
49 import org.opendaylight.vpnservice.mdsalutil.MetaDataUtil;
50 import org.opendaylight.vpnservice.mdsalutil.NwConstants;
51 import org.opendaylight.vpnservice.itm.globals.ITMConstants;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.Bucket;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.services.info.BoundServices;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
60 import org.opendaylight.vpnservice.mdsalutil.*;
61 import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
62 import org.opendaylight.vpnservice.neutronvpn.api.l2gw.L2GatewayDevice;
63 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.services.info.BoundServices;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.ElanDpnInterfaces;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.ElanForwardingTables;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.ElanInterfaces;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan._interface.forwarding.entries.ElanInterfaceMac;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan._interface.forwarding.entries.ElanInterfaceMacBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan._interface.forwarding.entries.ElanInterfaceMacKey;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesList;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfaces;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfacesBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfacesKey;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.forwarding.tables.MacTable;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.forwarding.tables.MacTableKey;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstance;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstanceBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.interfaces.ElanInterface;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.state.Elan;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.state.ElanBuilder;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.state.ElanKey;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntry;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntryBuilder;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntryKey;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.OdlInterfaceRpcService;
91 import org.opendaylight.yangtools.concepts.ListenerRegistration;
92 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
93 import org.slf4j.Logger;
94 import org.slf4j.LoggerFactory;
96 import com.google.common.base.Optional;
97 import com.google.common.base.Preconditions;
98 import com.google.common.collect.Lists;
102 * Class in charge of handling creations, modifications and removals of ElanInterfaces.
104 * @see org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.interfaces.ElanInterface
107 public class ElanInterfaceManager extends AbstractDataChangeListener<ElanInterface> implements AutoCloseable {
109 private static ElanInterfaceManager elanInterfaceManager = new ElanInterfaceManager();
110 private ListenerRegistration<DataChangeListener> elanInterfaceListenerRegistration;
111 private ListenerRegistration<DataChangeListener> itmInterfaceListenerRegistration;
112 private OdlInterfaceRpcService interfaceManagerRpcService;
113 private DataBroker broker;
114 private IMdsalApiManager mdsalManager;
115 private IInterfaceManager interfaceManager;
116 private IdManagerService idManager;
118 private ElanForwardingEntriesHandler elanForwardingEntriesHandler;
119 private Map<String, ConcurrentLinkedQueue<ElanInterface>> unProcessedElanInterfaces =
120 new ConcurrentHashMap<String, ConcurrentLinkedQueue<ElanInterface>> ();
122 private static final Logger logger = LoggerFactory.getLogger(ElanInterfaceManager.class);
124 public ElanInterfaceManager() {
125 super(ElanInterface.class);
128 public static ElanInterfaceManager getElanInterfaceManager() {
129 return elanInterfaceManager;
132 public void setMdSalApiManager(IMdsalApiManager mdsalManager) {
133 this.mdsalManager = mdsalManager;
136 public void setInterfaceManagerRpcService(OdlInterfaceRpcService ifManager) {
137 this.interfaceManagerRpcService = ifManager;
140 public void setElanForwardingEntriesHandler(ElanForwardingEntriesHandler elanForwardingEntriesHandler) {
141 this.elanForwardingEntriesHandler = elanForwardingEntriesHandler;
144 public void setInterfaceManager(IInterfaceManager interfaceManager) {
145 this.interfaceManager = interfaceManager;
148 public void setDataBroker(DataBroker broker) {
149 this.broker = broker;
153 public void close() throws Exception {
154 if (elanInterfaceListenerRegistration != null) {
156 elanInterfaceListenerRegistration.close();
157 } catch (final Exception e) {
158 logger.error("Error when cleaning up DataChangeListener.", e);
160 elanInterfaceListenerRegistration = null;
164 public void registerListener() {
166 elanInterfaceListenerRegistration = broker.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
167 getElanInterfaceWildcardPath(), ElanInterfaceManager.this, DataChangeScope.SUBTREE);
168 } catch (final Exception e) {
169 logger.error("ELAN Interface DataChange listener registration failed !", e);
170 throw new IllegalStateException("ELAN Interface registration Listener failed.", e);
174 private InstanceIdentifier<?> getElanInterfaceWildcardPath() {
175 return InstanceIdentifier.create(ElanInterfaces.class).child(ElanInterface.class);
178 public void setIdManager(IdManagerService idManager) {
179 this.idManager = idManager;
183 protected void remove(InstanceIdentifier<ElanInterface> identifier, ElanInterface del) {
184 String interfaceName = del.getName();
185 ElanInstance elanInfo = ElanUtils.getElanInstanceByName(del.getElanInstanceName());
186 removeElanInterface(elanInfo, interfaceName);
189 public void removeElanService(ElanInterface del, InterfaceInfo interfaceInfo) {
190 ElanInstance elanInstance = ElanUtils.getElanInstanceByName(del.getElanInstanceName());
191 String interfaceName = del.getName();
192 removeElanInterface(elanInstance, interfaceInfo);
193 unbindService(elanInstance, interfaceName);
196 public void removeElanInterface(ElanInstance elanInfo, String interfaceName) {
197 String elanName = elanInfo.getElanInstanceName();
198 InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
200 if (interfaceInfo == null) {
201 // Interface does not exist in ConfigDS, so lets remove everything about that interface related to Elan
202 ElanInterfaceMac elanInterfaceMac = ElanUtils.getElanInterfaceMacByInterfaceName(interfaceName);
203 if(elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null) {
204 List<MacEntry> macEntries = elanInterfaceMac.getMacEntry();
205 for(MacEntry macEntry : macEntries) {
206 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getMacEntryOperationalDataPath(elanName, macEntry.getMacAddress()));
209 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName));
210 Elan elanState = ElanUtils.getElanByName(elanName);
211 List<String> elanInterfaces = elanState.getElanInterfaces();
212 elanInterfaces.remove(interfaceName);
213 if(elanInterfaces.isEmpty()) {
214 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanName));
215 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanMacTableOperationalDataPath(elanName));
216 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInfoEntriesOperationalDataPath(elanInfo.getElanTag()));
218 Elan updateElanState = new ElanBuilder().setElanInterfaces(elanInterfaces).setName(elanName).setKey(new ElanKey(elanName)).build();
219 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanName), updateElanState);
222 removeElanInterface(elanInfo, interfaceInfo);
223 unbindService(elanInfo, interfaceName);
227 private void removeElanInterface(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
229 BigInteger dpId = interfaceInfo.getDpId();
230 String elanName = elanInfo.getElanInstanceName();
231 String interfaceName = interfaceInfo.getInterfaceName();
232 Elan elanState = ElanUtils.getElanByName(elanName);
233 logger.debug("Removing the Interface:{} from elan:{}", interfaceName, elanName);
234 InstanceIdentifier<ElanInterfaceMac> elanInterfaceId = ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName);
235 Optional<ElanInterfaceMac> existingElanInterface = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanInterfaceId);
236 if(existingElanInterface.isPresent()) {
237 List<PhysAddress> macAddresses = new ArrayList<PhysAddress>();
238 List<MacEntry> existingMacEntries = existingElanInterface.get().getMacEntry();
239 List<MacEntry> macEntries = new ArrayList<>();
240 if (existingMacEntries != null && !existingMacEntries.isEmpty()) {
241 macEntries.addAll(existingMacEntries);
243 if(!macEntries.isEmpty()) {
244 for (MacEntry macEntry : macEntries) {
245 logger.debug("removing the mac-entry:{} present on elanInterface:{}", macEntry.getMacAddress().getValue(), interfaceName);
246 elanForwardingEntriesHandler.deleteElanInterfaceForwardingEntries(elanInfo, interfaceInfo, macEntry);
247 macAddresses.add(macEntry.getMacAddress());
250 // Removing all those MACs from External Devices belonging to this ELAN
251 if ( elanInfo.getVni() != null && elanInfo.getVni() != 0 ) {
252 ElanL2GatewayUtils.removeMacsFromElanExternalDevices(elanInfo, macAddresses);
257 *This condition check is mainly to get DPN-ID in pre-provision deletion scenario after stopping CSS
259 if(dpId.equals(ElanConstants.INVALID_DPN)) {
260 ElanDpnInterfacesList elanDpnInterfacesList = ElanUtils.getElanDpnInterfacesList(elanName);
261 if(elanDpnInterfacesList != null && !elanDpnInterfacesList.getDpnInterfaces().isEmpty()) {
262 List<DpnInterfaces> dpnIfList = elanDpnInterfacesList.getDpnInterfaces();
263 for (DpnInterfaces dpnInterface : dpnIfList) {
264 DpnInterfaces dpnIfLists = ElanUtils.getElanInterfaceInfoByElanDpn(elanName, dpnInterface.getDpId());
265 if (dpnIfLists.getInterfaces().contains(interfaceName)) {
266 logger.debug("deleting the elanInterface from the ElanDpnInterface cache in pre-provision scenario of elan:{} dpn:{} interfaceName:{}", elanName, dpId, interfaceName);
267 removeElanDpnInterfaceFromOperationalDataStore(elanName, dpId, interfaceName);
273 removeElanDpnInterfaceFromOperationalDataStore(elanName, dpId, interfaceName);
276 removeStaticELanFlows(elanInfo, interfaceInfo);
277 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, elanInterfaceId);
278 List<String> elanInterfaces = elanState.getElanInterfaces();
279 elanInterfaces.remove(interfaceName);
281 if(elanInterfaces.isEmpty()) {
282 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanName));
283 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnOperationDataPath(elanName));
284 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanMacTableOperationalDataPath(elanName));
285 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInfoEntriesOperationalDataPath(elanInfo.getElanTag()));
286 //ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION, ElanUtils.getElanInstanceConfigurationDataPath(elanName));
288 Elan updateElanState = new ElanBuilder().setElanInterfaces(elanInterfaces).setName(elanName).setKey(new ElanKey(elanName)).build();
289 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanName), updateElanState);
293 private void removeElanDpnInterfaceFromOperationalDataStore(String elanName, BigInteger dpId, String interfaceName) {
294 DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanName, dpId);
295 if(dpnInterfaces != null) {
296 List<String> interfaceLists = dpnInterfaces.getInterfaces();
297 interfaceLists.remove(interfaceName);
299 if (interfaceLists == null || interfaceLists.isEmpty()) {
300 deleteElanDpnInterface(elanName, dpId);
301 ElanL2GatewayMulticastUtils.updateRemoteMcastMacOnElanL2GwDevices(elanName);
303 updateElanDpnInterfacesList(elanName, dpId, interfaceLists);
309 protected void update(InstanceIdentifier<ElanInterface> identifier, ElanInterface original, ElanInterface update) {
310 // updating the static-Mac Entries for the existing elanInterface
311 String elanName = update.getElanInstanceName();
312 String interfaceName = update.getName();
313 InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
314 List<PhysAddress> existingPhysAddress = original.getStaticMacEntries();
315 List<PhysAddress> updatedPhysAddress = update.getStaticMacEntries();
316 if(updatedPhysAddress != null && !updatedPhysAddress.isEmpty()) {
317 List<PhysAddress> existingClonedPhyAddress = new ArrayList<>();
318 if(existingPhysAddress != null && !existingPhysAddress.isEmpty()) {
319 existingClonedPhyAddress.addAll(0, existingPhysAddress);
320 existingPhysAddress.removeAll(updatedPhysAddress);
321 updatedPhysAddress.removeAll(existingClonedPhyAddress);
322 // removing the PhyAddress which are not presented in the updated List
323 for(PhysAddress physAddress: existingPhysAddress) {
324 removeInterfaceStaticMacEntires(elanName, interfaceName, physAddress);
327 // Adding the new PhysAddress which are presented in the updated List
328 if(updatedPhysAddress.size() > 0) {
329 for(PhysAddress physAddress: updatedPhysAddress) {
330 InstanceIdentifier<MacEntry> macId = getMacEntryOperationalDataPath(elanName, physAddress);
331 Optional<MacEntry> existingMacEntry = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, macId);
332 if(existingMacEntry.isPresent()) {
333 elanForwardingEntriesHandler.updateElanInterfaceForwardingTablesList(elanName, interfaceName, existingMacEntry.get().getInterface(), existingMacEntry.get());
335 elanForwardingEntriesHandler.addElanInterfaceForwardingTableList(ElanUtils.getElanInstanceByName(elanName), interfaceName, physAddress);
339 } else if(existingPhysAddress != null && !existingPhysAddress.isEmpty()) {
340 for( PhysAddress physAddress : existingPhysAddress) {
341 removeInterfaceStaticMacEntires(elanName, interfaceName, physAddress);
347 protected void add(InstanceIdentifier<ElanInterface> identifier, ElanInterface elanInterfaceAdded) {
348 String elanInstanceName = elanInterfaceAdded.getElanInstanceName();
349 String interfaceName = elanInterfaceAdded.getName();
350 InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
351 if (interfaceInfo == null) {
352 logger.warn("Interface {} is removed from Interface Oper DS due to port down ", interfaceName);
355 ElanInstance elanInstance = ElanUtils.getElanInstanceByName(elanInstanceName);
357 if (elanInstance == null) {
358 elanInstance = new ElanInstanceBuilder().setElanInstanceName(elanInstanceName).setDescription(elanInterfaceAdded.getDescription()).build();
359 //Add the ElanInstance in the Configuration data-store
360 ElanUtils.updateOperationalDataStore(broker, idManager, elanInstance);
361 elanInstance = ElanUtils.getElanInstanceByName(elanInstanceName);
365 Long elanTag = elanInstance.getElanTag();
366 // If elan tag is not updated, then put the elan interface into unprocessed entry map and entry. Let entries
367 // in this map get processed during ELAN update DCN.
368 if (elanTag == null) {
369 ConcurrentLinkedQueue<ElanInterface> elanInterfaces = unProcessedElanInterfaces.get(elanInstanceName);
370 if (elanInterfaces == null) {
371 elanInterfaces = new ConcurrentLinkedQueue<ElanInterface>();
373 elanInterfaces.add(elanInterfaceAdded);
374 unProcessedElanInterfaces.put(elanInstanceName, elanInterfaces);
377 addElanInterface(elanInterfaceAdded, interfaceInfo, elanInstance);
380 void handleunprocessedElanInterfaces(ElanInstance elanInstance) {
381 Queue<ElanInterface> elanInterfaces = unProcessedElanInterfaces.get(elanInstance.getElanInstanceName());
382 if (elanInterfaces == null || elanInterfaces.isEmpty()) {
385 for (ElanInterface elanInterface: elanInterfaces) {
386 String interfaceName = elanInterface.getName();
387 InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
388 addElanInterface(elanInterface, interfaceInfo, elanInstance);
392 void programRemoteDmacFlow(ElanInstance elanInstance, InterfaceInfo interfaceInfo){
393 ElanDpnInterfacesList elanDpnInterfacesList = ElanUtils.getElanDpnInterfacesList(elanInstance.getElanInstanceName());
394 List<DpnInterfaces> dpnInterfaceLists = elanDpnInterfacesList.getDpnInterfaces();
395 for(DpnInterfaces dpnInterfaces : dpnInterfaceLists){
396 if(dpnInterfaces.getDpId().equals(interfaceInfo.getDpId())) {
399 List<String> remoteElanInterfaces = dpnInterfaces.getInterfaces();
400 for(String remoteIf : remoteElanInterfaces) {
401 ElanInterfaceMac elanIfMac = ElanUtils.getElanInterfaceMacByInterfaceName(remoteIf);
402 InterfaceInfo remoteInterface = interfaceManager.getInterfaceInfo(remoteIf);
403 if(elanIfMac == null) {
406 List<MacEntry> remoteMacEntries = elanIfMac.getMacEntry();
407 if(remoteMacEntries != null) {
408 for (MacEntry macEntry : remoteMacEntries) {
409 PhysAddress physAddress = macEntry.getMacAddress();
410 ElanUtils.setupRemoteDmacFlow(interfaceInfo.getDpId(), remoteInterface.getDpId(),
411 remoteInterface.getInterfaceTag(),
412 elanInstance.getElanTag(),
413 physAddress.getValue(),
414 elanInstance.getElanInstanceName());
421 void addElanInterface(ElanInterface elanInterface, InterfaceInfo interfaceInfo, ElanInstance elanInstance) {
422 Preconditions.checkNotNull(elanInstance, "elanInstance cannot be null");
423 Preconditions.checkNotNull(interfaceInfo, "interfaceInfo cannot be null");
424 Preconditions.checkNotNull(elanInterface, "elanInterface cannot be null");
426 String interfaceName = elanInterface.getName();
427 String elanInstanceName = elanInterface.getElanInstanceName();
428 List<PhysAddress> staticMacAddresses = elanInterface.getStaticMacEntries();
430 Elan elanInfo = ElanUtils.getElanByName(elanInstanceName);
431 if(elanInfo == null) {
432 ElanUtils.updateOperationalDataStore(broker, idManager, elanInstance);
435 // Specific actions to the DPN where the ElanInterface has been added, for example, programming the
436 // External tunnel table if needed or adding the ElanInterface to the DpnInterfaces in the operational DS.
437 BigInteger dpId = ( interfaceInfo != null ) ? dpId = interfaceInfo.getDpId() : null;
438 if(dpId != null && !dpId.equals(ElanConstants.INVALID_DPN)) {
439 InstanceIdentifier<DpnInterfaces> elanDpnInterfaces = ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId);
440 Optional<DpnInterfaces> existingElanDpnInterfaces = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanDpnInterfaces);
441 if (!existingElanDpnInterfaces.isPresent()) {
442 // ELAN's 1st ElanInterface added to this DPN
443 createElanInterfacesList(elanInstanceName, interfaceName, dpId);
445 * Install remote DMAC flow.
446 * This is required since this DPN is added later to the elan instance
447 * and remote DMACs of other interfaces in this elan instance are not present in the current dpn.
449 programRemoteDmacFlow(elanInstance, interfaceInfo);
450 // The 1st ElanInterface in a DPN must program the Ext Tunnel table, but only if Elan has VNI
451 if ( elanInstance.getVni() != null && elanInstance.getVni().longValue() != 0 ) {
452 setExternalTunnelTable(dpId, elanInstance);
454 ElanL2GatewayMulticastUtils.updateRemoteMcastMacOnElanL2GwDevices(elanInstanceName);
456 List<String> elanInterfaces = existingElanDpnInterfaces.get().getInterfaces();
457 elanInterfaces.add(interfaceName);
458 if (elanInterfaces.size() == 1) {//1st dpn interface
459 ElanL2GatewayMulticastUtils.updateRemoteMcastMacOnElanL2GwDevices(elanInstanceName);
461 updateElanDpnInterfacesList(elanInstanceName, dpId, elanInterfaces);
465 // add code to install Local/Remote BC group, unknow DMAC entry, terminating service table flow entry
466 // call bindservice of interfacemanager to create ingress table flow enty.
467 //Add interface to the ElanInterfaceForwardingEntires Container
468 createElanInterfaceTablesList(interfaceName);
469 createElanStateList(elanInstanceName, interfaceName);
470 if (interfaceInfo != null) {
471 installFlowsAndGroups(elanInstance, interfaceInfo);
473 // add the static mac addresses
474 if (staticMacAddresses != null) {
475 boolean isInterfaceOperational = isOperational(interfaceInfo);
476 for (PhysAddress physAddress : staticMacAddresses) {
477 InstanceIdentifier<MacEntry> macId = getMacEntryOperationalDataPath(elanInstanceName, physAddress);
478 Optional<MacEntry> existingMacEntry = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, macId);
479 if (existingMacEntry.isPresent()) {
480 elanForwardingEntriesHandler.updateElanInterfaceForwardingTablesList(elanInstanceName, interfaceName, existingMacEntry.get().getInterface(), existingMacEntry.get());
482 elanForwardingEntriesHandler.addElanInterfaceForwardingTableList(elanInstance, interfaceName, physAddress);
485 if ( isInterfaceOperational ) {
486 // Setting SMAC, DMAC, UDMAC in this DPN and also in other DPNs
487 ElanUtils.setupMacFlows(elanInstance, interfaceInfo, ElanConstants.STATIC_MAC_TIMEOUT, physAddress.getValue());
491 if( isInterfaceOperational ) {
492 // Add MAC in TOR's remote MACs via OVSDB. Outside of the loop on purpose.
493 ElanL2GatewayUtils.installMacsInElanExternalDevices(elanInstance, dpId, staticMacAddresses);
498 protected void removeInterfaceStaticMacEntires(String elanInstanceName, String interfaceName, PhysAddress physAddress) {
499 InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
500 InstanceIdentifier<MacEntry> macId = getMacEntryOperationalDataPath(elanInstanceName, physAddress);
501 Optional<MacEntry> existingMacEntry = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, macId);
503 if(!existingMacEntry.isPresent()) {
507 MacEntry macEntry = new MacEntryBuilder().setMacAddress(physAddress).setInterface(interfaceName).setKey(new MacEntryKey(physAddress)).build();
508 elanForwardingEntriesHandler.deleteElanInterfaceForwardingEntries(ElanUtils.getElanInstanceByName(elanInstanceName), interfaceInfo, macEntry);
509 elanForwardingEntriesHandler.deleteElanInterfaceMacForwardingEntries(interfaceName, physAddress);
513 private InstanceIdentifier<MacEntry> getMacEntryOperationalDataPath(String elanName, PhysAddress physAddress) {
514 return InstanceIdentifier.builder(ElanForwardingTables.class).child(MacTable.class,
515 new MacTableKey(elanName)).child(MacEntry.class, new MacEntryKey(physAddress)).build();
518 public void installFlowsAndGroups(final ElanInstance elanInfo, final InterfaceInfo interfaceInfo) {
519 if (isOperational(interfaceInfo)) {
521 // LocalBroadcast Group creation with elan-Interfaces
522 setupElanBroadcastGroups(elanInfo, interfaceInfo);
524 setupLocalBroadcastGroups(elanInfo, interfaceInfo);
525 //Terminating Service , UnknownDMAC Table.
526 setupTerminateServiceTable(elanInfo, interfaceInfo);
527 setupUnknownDMacTable(elanInfo, interfaceInfo);
528 setupFilterEqualsTable(elanInfo, interfaceInfo);
529 // bind the Elan service to the Interface
530 bindService(elanInfo, interfaceInfo.getInterfaceName());
532 //update the remote-DPNs remoteBC group entry with Tunnels
533 setElanBCGrouponOtherDpns(elanInfo, interfaceInfo);
537 public void setupFilterEqualsTable(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
538 int ifTag = interfaceInfo.getInterfaceTag();
539 Flow flow = MDSALUtil.buildFlowNew(ElanConstants.ELAN_FILTER_EQUALS_TABLE, getFlowRef(ElanConstants.ELAN_FILTER_EQUALS_TABLE, ifTag),
540 9, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_FILTER_EQUALS.add(BigInteger.valueOf(ifTag)), getTunnelIdMatchForFilterEqualsLPortTag(ifTag), ElanUtils.getInstructionsInPortForOutGroup(interfaceInfo.getInterfaceName()));
542 mdsalManager.installFlow(interfaceInfo.getDpId(), flow);
544 Flow flowEntry = MDSALUtil.buildFlowNew(ElanConstants.ELAN_FILTER_EQUALS_TABLE, getFlowRef(ElanConstants.ELAN_FILTER_EQUALS_TABLE, 1000+ifTag),
545 10, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_FILTER_EQUALS.add(BigInteger.valueOf(ifTag)), getMatchesForFilterEqualsLPortTag(ifTag),
546 MDSALUtil.buildInstructionsDrop());
548 mdsalManager.installFlow(interfaceInfo.getDpId(), flowEntry);
551 public void removeFilterEqualsTable(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
552 int ifTag = interfaceInfo.getInterfaceTag();
553 Flow flow = MDSALUtil.buildFlowNew(ElanConstants.ELAN_FILTER_EQUALS_TABLE, getFlowRef(ElanConstants.ELAN_FILTER_EQUALS_TABLE, ifTag),
554 9, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_FILTER_EQUALS.add(BigInteger.valueOf(ifTag)), getTunnelIdMatchForFilterEqualsLPortTag(ifTag), ElanUtils.getInstructionsInPortForOutGroup(interfaceInfo.getInterfaceName()));
556 mdsalManager.removeFlow(interfaceInfo.getDpId(), flow);
558 Flow flowEntity = MDSALUtil.buildFlowNew(ElanConstants.ELAN_FILTER_EQUALS_TABLE, getFlowRef(ElanConstants.ELAN_FILTER_EQUALS_TABLE, 1000+ifTag),
559 10, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_FILTER_EQUALS.add(BigInteger.valueOf(ifTag)), getMatchesForFilterEqualsLPortTag(ifTag),
560 MDSALUtil.buildInstructionsDrop());
562 mdsalManager.removeFlow(interfaceInfo.getDpId(), flowEntity);
565 private List<Bucket> getRemoteBCGroupBucketInfos(ElanInstance elanInfo,
566 int bucketKeyStart, InterfaceInfo interfaceInfo) {
567 BigInteger dpnId = interfaceInfo.getDpId();
568 int elanTag = elanInfo.getElanTag().intValue();
569 int bucketId = bucketKeyStart;
570 List<Bucket> listBuckets = new ArrayList<Bucket>();
571 ElanDpnInterfacesList elanDpns = ElanUtils.getElanDpnInterfacesList(elanInfo.getElanInstanceName());
572 if(elanDpns != null) {
573 List<DpnInterfaces> dpnInterfaceses = elanDpns.getDpnInterfaces();
574 for(DpnInterfaces dpnInterface : dpnInterfaceses) {
575 if(ElanUtils.isDpnPresent(dpnInterface.getDpId()) && dpnInterface.getDpId() != dpnId && dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty()) {
577 List<Action> listAction = ElanUtils.getInternalItmEgressAction(dpnId, dpnInterface.getDpId(), elanTag);
578 listBuckets.add(MDSALUtil.buildBucket(listAction, MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
580 } catch (Exception ex) {
581 logger.error( "Logical Group Interface not found between source Dpn - {}, destination Dpn - {} " ,dpnId, dpnInterface.getDpId() );
585 List<Bucket> elanL2GwDevicesBuckets = getRemoteBCGroupBucketsOfElanL2GwDevices(elanInfo, dpnId, bucketId);
586 listBuckets.addAll(elanL2GwDevicesBuckets);
591 private List<Bucket> getRemoteBCGroupBuckets(ElanInstance elanInfo,
592 InterfaceInfo interfaceInfo, int bucketId) {
593 BigInteger dpnId = interfaceInfo.getDpId();
594 int elanTag = elanInfo.getElanTag().intValue();
595 List<Bucket> listBucketInfo = new ArrayList<Bucket>();
596 ElanDpnInterfacesList elanDpns = ElanUtils.getElanDpnInterfacesList(elanInfo.getElanInstanceName());
597 if(elanDpns != null) {
598 List<DpnInterfaces> dpnInterfaceses = elanDpns.getDpnInterfaces();
599 for(DpnInterfaces dpnInterface : dpnInterfaceses) {
600 if(ElanUtils.isDpnPresent(dpnInterface.getDpId()) && dpnInterface.getDpId() != dpnId && dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty()) {
602 List<Action> listActionInfo = ElanUtils.getInternalItmEgressAction(dpnId, dpnInterface.getDpId(), elanTag);
603 listBucketInfo.add(MDSALUtil.buildBucket(listActionInfo, 0, bucketId, 0xffffffffL, 0xffffffffL));
605 } catch (Exception ex) {
606 logger.error( "Logical Group Interface not found between source Dpn - {}, destination Dpn - {} " ,dpnId, dpnInterface.getDpId() );
611 List<Bucket> elanL2GwDevicesBuckets = getRemoteBCGroupBucketsOfElanL2GwDevices(elanInfo, dpnId, bucketId);
612 listBucketInfo.addAll(elanL2GwDevicesBuckets);
614 return listBucketInfo;
617 private void setElanBCGrouponOtherDpns(ElanInstance elanInfo,
618 InterfaceInfo interfaceInfo) {
619 BigInteger dpnId = interfaceInfo.getDpId();
620 int elanTag = elanInfo.getElanTag().intValue();
621 long groupId = ElanUtils.getElanRemoteBCGID(elanTag);
622 List<Bucket> listBucket = new ArrayList<Bucket>();
624 ElanDpnInterfacesList elanDpns = ElanUtils.getElanDpnInterfacesList(elanInfo.getElanInstanceName());
625 if(elanDpns != null) {
626 List<DpnInterfaces> dpnInterfaceses = elanDpns.getDpnInterfaces();
627 for(DpnInterfaces dpnInterface : dpnInterfaceses) {
628 List<Bucket> remoteListBucketInfo = new ArrayList<Bucket>();
629 if(ElanUtils.isDpnPresent(dpnInterface.getDpId()) && !dpnInterface.getDpId().equals(dpnId) && dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty()) {
630 for(String ifName : dpnInterface.getInterfaces()) {
631 // In case if there is a InterfacePort in the cache which is not in
632 // operational state, skip processing it
633 InterfaceInfo ifInfo = interfaceManager.getInterfaceInfoFromOperationalDataStore(ifName, interfaceInfo.getInterfaceType());
634 if (!isOperational(ifInfo)) {
638 listBucket.add(MDSALUtil.buildBucket(getInterfacePortActions(ifInfo), MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
641 remoteListBucketInfo.addAll(listBucket);
642 for(DpnInterfaces otherFes : dpnInterfaceses) {
643 if (ElanUtils.isDpnPresent(otherFes.getDpId()) && otherFes.getDpId() != dpnInterface.getDpId()
644 && otherFes.getInterfaces() != null && ! otherFes.getInterfaces().isEmpty()) {
646 List<Action> remoteListActionInfo = ElanUtils.getInternalItmEgressAction(dpnInterface.getDpId(), otherFes.getDpId(), elanTag);
647 remoteListBucketInfo.add(MDSALUtil.buildBucket(remoteListActionInfo, MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT,MDSALUtil.WATCH_GROUP));
649 } catch (Exception ex) {
650 logger.error( "Logical Group Interface not found between source Dpn - {}, destination Dpn - {} " ,dpnInterface.getDpId(), otherFes.getDpId() );
655 List<Bucket> elanL2GwDevicesBuckets = getRemoteBCGroupBucketsOfElanL2GwDevices(elanInfo, dpnId,
657 remoteListBucketInfo.addAll(elanL2GwDevicesBuckets);
659 if (remoteListBucketInfo.size() == 0) {
660 logger.debug( "No ITM is present on Dpn - {} " ,dpnInterface.getDpId());
663 Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, MDSALUtil.buildBucketLists(remoteListBucketInfo));
664 mdsalManager.syncInstallGroup(dpnInterface.getDpId(), group, ElanConstants.DELAY_TIME_IN_MILLISECOND);
670 private void updateRemoteBCGrouponDpnTunnelEvent(ElanInstance elanInfo,
671 InterfaceInfo interfaceInfo, BigInteger dstDpId) {
672 int elanTag = elanInfo.getElanTag().intValue();
673 long groupId = ElanUtils.getElanRemoteBCGID(elanTag);
674 List<DpnInterfaces> elanDpns = ElanUtils.getInvolvedDpnsInElan(elanInfo.getElanInstanceName());
675 if(elanDpns != null) {
676 for(DpnInterfaces dpnInterface : elanDpns) {
678 List<Bucket> remoteListBucket = new ArrayList<Bucket>();
679 if(ElanUtils.isDpnPresent(dstDpId) && dpnInterface.getDpId().equals(dstDpId) && dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty()) {
681 List<Action> remoteListActionInfo = ElanUtils.getInternalItmEgressAction(interfaceInfo.getDpId(), dstDpId, elanTag);
682 remoteListBucket.add(MDSALUtil.buildBucket(remoteListActionInfo, MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
684 } catch (Exception ex) {
685 logger.error( "Logical Group Interface not found between source Dpn - {}, destination Dpn - {} " ,dpnInterface.getDpId(), dstDpId);
688 List<Action> remoteListActionInfo = new ArrayList<Action>();
689 remoteListActionInfo.add(new ActionInfo(ActionType.group, new String[] {String.valueOf(ElanUtils.getElanLocalBCGID(elanTag))}).buildAction());
690 remoteListBucket.add(MDSALUtil.buildBucket(remoteListActionInfo, MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
692 List<Bucket> elanL2GwDevicesBuckets = getRemoteBCGroupBucketsOfElanL2GwDevices(elanInfo, dstDpId, bucketId);
693 remoteListBucket.addAll(elanL2GwDevicesBuckets);
695 Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, MDSALUtil.buildBucketLists(remoteListBucket));
696 mdsalManager.syncInstallGroup(interfaceInfo.getDpId(), group, ElanConstants.DELAY_TIME_IN_MILLISECOND);
705 * Returns the bucket info with the given interface as the only bucket.
707 private Bucket getLocalBCGroupBucketInfo(InterfaceInfo interfaceInfo, int bucketIdStart) {
708 return MDSALUtil.buildBucket(getInterfacePortActions(interfaceInfo), MDSALUtil.GROUP_WEIGHT, bucketIdStart, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP);
711 private List<MatchInfo> getMatchesForElanTag(Long elanTag) {
712 List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
714 mkMatches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
715 ElanUtils.getElanMetadataLabel(elanTag),
716 MetaDataUtil.METADATA_MASK_SERVICE }));
721 private List<MatchInfo> buildMatchesForVni(Long vni) {
722 List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
723 MatchInfo match = new MatchInfo(MatchFieldType.tunnel_id,
724 new BigInteger[]{BigInteger.valueOf(vni)} );
725 mkMatches.add(match);
729 private List<Instruction> getInstructionsForOutGroup(
731 List<Instruction> mkInstructions = new ArrayList<Instruction>();
732 List <Action> actions = new ArrayList <Action> ();
733 actions.add(new ActionInfo(ActionType.group, new String[]{Long.toString(groupId)}).buildAction());
734 mkInstructions.add(MDSALUtil.getWriteActionsInstruction(actions, 0));
735 return mkInstructions;
738 private List<MatchInfo> getMatchesForElanTag(long elanTag, boolean isSHFlagSet) {
739 List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
741 mkMatches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
742 ElanUtils.getElanMetadataLabel(elanTag, isSHFlagSet),
743 MetaDataUtil.METADATA_MASK_SERVICE_SH_FLAG}));
751 * Builds the list of instructions to be installed in the External Tunnel table (38), which so far
752 * consists in writing the elanTag in metadata and send packet to the new DHCP table
754 * @param elanTag elanTag to be written in metadata when flow is selected
755 * @return the instructions ready to be installed in a flow
757 private List<InstructionInfo> getInstructionsExtTunnelTable(Long elanTag) {
758 List<InstructionInfo> mkInstructions = new ArrayList<InstructionInfo>();
759 mkInstructions.add(new InstructionInfo(InstructionType.write_metadata,
761 ElanUtils.getElanMetadataLabel(elanTag),
762 ElanUtils.getElanMetadataMask()
764 // TODO (eperefr) We should point to SMAC or DMAC depending on a configuration property to enable
766 mkInstructions.add(new InstructionInfo(InstructionType.goto_table,
767 new long[] { ElanConstants.ELAN_DMAC_TABLE }));
769 return mkInstructions;
772 public void removeFlowsAndGroups(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
773 removeStaticELanFlows(elanInfo, interfaceInfo);
774 unbindService(elanInfo, interfaceInfo.getInterfaceName());
777 public void installMacAddressTables(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
779 String interfaceName = interfaceInfo.getInterfaceName();
780 BigInteger currentDpn = interfaceInfo.getDpId();
781 ElanInterfaceMac elanInterfaceMac = ElanUtils.getElanInterfaceMacByInterfaceName(interfaceName);
782 if(elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null) {
783 List<MacEntry> macEntries = elanInterfaceMac.getMacEntry();
784 for(MacEntry macEntry : macEntries) {
785 PhysAddress physAddress = macEntry.getMacAddress();
786 ElanUtils.setupMacFlows(elanInfo,
788 macEntry.isIsStaticAddress()
789 ? ElanConstants.STATIC_MAC_TIMEOUT
790 : elanInfo.getMacTimeout(), physAddress.getValue());
792 //Programming the remoteDMACFlows
793 ElanDpnInterfacesList elanDpnInterfacesList = ElanUtils.getElanDpnInterfacesList(elanInfo.getElanInstanceName());
794 List<DpnInterfaces> dpnInterfaceLists = elanDpnInterfacesList.getDpnInterfaces();
795 for(DpnInterfaces dpnInterfaces : dpnInterfaceLists){
796 if(dpnInterfaces.getDpId().equals(interfaceInfo.getDpId())) {
799 List<String> remoteElanInterfaces = dpnInterfaces.getInterfaces();
800 for(String remoteIf : remoteElanInterfaces) {
801 ElanInterfaceMac elanIfMac = ElanUtils.getElanInterfaceMacByInterfaceName(remoteIf);
802 InterfaceInfo remoteInterface = interfaceManager.getInterfaceInfo(remoteIf);
803 if(elanIfMac == null) {
806 List<MacEntry> remoteMacEntries = elanIfMac.getMacEntry();
807 if(remoteMacEntries != null) {
808 for (MacEntry macEntry : remoteMacEntries) {
809 PhysAddress physAddress = macEntry.getMacAddress();
810 ElanUtils.installDmacFlowsToInternalRemoteMac(currentDpn, remoteInterface.getDpId(),
811 remoteInterface.getInterfaceTag(),
812 elanInfo.getElanTag(),
813 physAddress.getValue(),
814 elanInfo.getElanInstanceName());
822 // Install DMAC entry on dst DPN
823 public void installDMacAddressTables(ElanInstance elanInfo, InterfaceInfo interfaceInfo, BigInteger dstDpId) {
824 String interfaceName = interfaceInfo.getInterfaceName();
825 ElanInterfaceMac elanInterfaceMac = ElanUtils.getElanInterfaceMacByInterfaceName(interfaceName);
826 if(elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null) {
827 List<MacEntry> macEntries = elanInterfaceMac.getMacEntry();
828 for(MacEntry macEntry : macEntries) {
829 PhysAddress physAddress = macEntry.getMacAddress();
830 ElanUtils.setupDMacFlowonRemoteDpn(elanInfo, interfaceInfo, dstDpId, physAddress.getValue());
835 public void removeMacAddressTables(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
836 ElanInterfaceMac elanInterfaceMac = ElanUtils.getElanInterfaceMacByInterfaceName(interfaceInfo.getInterfaceName());
837 if(elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null) {
838 List<MacEntry> macEntries = elanInterfaceMac.getMacEntry();
839 for(MacEntry macEntry : macEntries) {
840 ElanUtils.deleteMacFlows(elanInfo, interfaceInfo, macEntry);
845 public void setupElanBroadcastGroups(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
846 List<Bucket> listBucket = new ArrayList<Bucket>();
848 BigInteger dpnId = interfaceInfo.getDpId();
849 long groupId = ElanUtils.getElanRemoteBCGID(elanInfo.getElanTag());
851 DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanInfo.getElanInstanceName(), dpnId);
852 for(String ifName : dpnInterfaces.getInterfaces()) {
853 // In case if there is a InterfacePort in the cache which is not in
854 // operational state, skip processing it
855 InterfaceInfo ifInfo = interfaceManager.getInterfaceInfoFromOperationalDataStore(ifName, interfaceInfo.getInterfaceType());
856 if (!isOperational(ifInfo)) {
860 listBucket.add(MDSALUtil.buildBucket(getInterfacePortActions(ifInfo), MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
863 List<Bucket> listBucketInfoRemote = getRemoteBCGroupBuckets(elanInfo, interfaceInfo, bucketId);
864 listBucket.addAll(listBucketInfoRemote);
866 Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, MDSALUtil.buildBucketLists(listBucket));
867 logger.trace("installing the localBroadCast Group:{}", group);
868 mdsalManager.syncInstallGroup(dpnId, group, ElanConstants.DELAY_TIME_IN_MILLISECOND);
871 public void setupLocalBroadcastGroups(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
872 List<Bucket> listBucket = new ArrayList<Bucket>();
874 BigInteger dpnId = interfaceInfo.getDpId();
875 long groupId = ElanUtils.getElanLocalBCGID(elanInfo.getElanTag());
877 DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanInfo.getElanInstanceName(), dpnId);
878 for(String ifName : dpnInterfaces.getInterfaces()) {
879 // In case if there is a InterfacePort in the cache which is not in
880 // operational state, skip processing it
881 InterfaceInfo ifInfo = interfaceManager.getInterfaceInfoFromOperationalDataStore(ifName, interfaceInfo.getInterfaceType());
882 if (!isOperational(ifInfo)) {
886 listBucket.add(MDSALUtil.buildBucket(getInterfacePortActions(ifInfo), MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
890 Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, MDSALUtil.buildBucketLists(listBucket));
891 logger.trace("installing the localBroadCast Group:{}", group);
892 mdsalManager.syncInstallGroup(dpnId, group, ElanConstants.DELAY_TIME_IN_MILLISECOND);
895 public void removeLocalBroadcastGroup(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
896 BigInteger dpnId = interfaceInfo.getDpId();
897 long groupId = ElanUtils.getElanLocalBCGID(elanInfo.getElanTag());
898 List<Bucket> listBuckets = new ArrayList<>();
900 listBuckets.add(getLocalBCGroupBucketInfo(interfaceInfo, bucketId));
901 //listBuckets.addAll(getRemoteBCGroupBucketInfos(elanInfo, 1, interfaceInfo));
902 Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, MDSALUtil.buildBucketLists(listBuckets));
903 logger.trace("deleted the localBroadCast Group:{}", group);
904 mdsalManager.syncRemoveGroup(dpnId, group);
907 public void removeElanBroadcastGroup(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
909 List<Bucket> listBuckets = new ArrayList<>();
910 listBuckets.add(getLocalBCGroupBucketInfo(interfaceInfo, bucketId));
912 listBuckets.addAll(getRemoteBCGroupBucketInfos(elanInfo, bucketId, interfaceInfo));
913 BigInteger dpnId = interfaceInfo.getDpId();
914 long groupId = ElanUtils.getElanRemoteBCGID(elanInfo.getElanTag());
915 Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, MDSALUtil.buildBucketLists(listBuckets));
916 logger.trace("deleting the remoteBroadCast group:{}", group);
917 mdsalManager.syncRemoveGroup(dpnId, group);
921 * Installs a flow in the External Tunnel table consisting in translating
922 * the VNI retrieved from the packet that came over a tunnel with a TOR into
923 * elanTag that will be used later in the ELANs pipeline.
930 public void setExternalTunnelTable(BigInteger dpnId, ElanInstance elanInfo) {
931 long elanTag = elanInfo.getElanTag();
932 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpnId,
933 NwConstants.EXTERNAL_TUNNEL_TABLE,
934 getFlowRef(NwConstants.EXTERNAL_TUNNEL_TABLE, elanTag),
936 elanInfo.getElanInstanceName(), // flowName
939 ITMConstants.COOKIE_ITM_EXTERNAL.add(BigInteger.valueOf(elanTag)),
940 buildMatchesForVni(elanInfo.getVni()),
941 getInstructionsExtTunnelTable(elanTag) );
943 mdsalManager.installFlow(flowEntity);
947 * Removes, from External Tunnel table, the flow that translates from VNI to elanTag.
948 * Important: ensure this method is only called whenever there is no other ElanInterface in the specified DPN
950 * @param dpnId DPN whose Ext Tunnel table is going to be modified
951 * @param elanInfo holds the elanTag needed for selecting the flow to be removed
953 public void unsetExternalTunnelTable(BigInteger dpnId, ElanInstance elanInfo) {
954 // TODO (eperefr): Use DataStoreJobCoordinator in order to avoid that removing the last ElanInstance plus
955 // adding a new one does (almost at the same time) are executed in that exact order
957 String flowId = getFlowRef(NwConstants.EXTERNAL_TUNNEL_TABLE, elanInfo.getElanTag());
958 FlowEntity flowEntity = new FlowEntity(dpnId);
959 flowEntity.setFlowId(flowId);
960 mdsalManager.removeFlow(flowEntity);
963 public void setupTerminateServiceTable(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
964 long elanTag = elanInfo.getElanTag();
965 Flow flowEntity = MDSALUtil.buildFlowNew(NwConstants.INTERNAL_TUNNEL_TABLE, getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE, elanTag),
966 5, String.format("%s:%d","ITM Flow Entry ",elanTag), 0, 0, ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(elanTag)), ElanUtils.getTunnelMatchesForServiceId((int)elanTag),
967 getInstructionsForOutGroup(ElanUtils.getElanLocalBCGID(elanTag)));
969 mdsalManager.installFlow(interfaceInfo.getDpId(), flowEntity);
972 public void setupUnknownDMacTable(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
973 long elanTag = elanInfo.getElanTag();
974 Flow flowEntity = MDSALUtil.buildFlowNew(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, getUnknownDmacFlowRef(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, elanTag, /*SH flag*/false),
975 5, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_UNKNOWN_DMAC.add(BigInteger.valueOf(elanTag)), getMatchesForElanTag(elanTag, /*SH flag*/false),
976 getInstructionsForOutGroup(ElanUtils.getElanRemoteBCGID(elanTag)));
978 mdsalManager.installFlow(interfaceInfo.getDpId(), flowEntity);
980 // only if vni is present in elanInfo, perform the following
981 if (elanInfo.getVni() != null && elanInfo.getVni() != 0) {
982 Flow flowEntity2 = MDSALUtil.buildFlowNew(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, getUnknownDmacFlowRef(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, elanTag, /*SH flag*/true),
983 5, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_UNKNOWN_DMAC.add(BigInteger.valueOf(elanTag)), getMatchesForElanTag(elanTag, /*SH flag*/true),
984 getInstructionsForOutGroup(ElanUtils.getElanLocalBCGID(elanTag)));
985 mdsalManager.installFlow(interfaceInfo.getDpId(), flowEntity2);
991 private void removeStaticELanFlows(final ElanInstance elanInfo, final InterfaceInfo interfaceInfo) {
992 BigInteger dpId = interfaceInfo.getDpId();
994 * If there are not elan ports, remove the unknown smac and default dmac
997 DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanInfo.getElanInstanceName(), dpId);
998 if (dpnInterfaces == null || dpnInterfaces.getInterfaces() == null || dpnInterfaces.getInterfaces().isEmpty()) {
999 // No more Elan Interfaces in this DPN
1000 logger.debug("deleting the elan: {} present on dpId: {}", elanInfo.getElanInstanceName(), dpId);
1001 removeDefaultTermFlow(dpId, elanInfo.getElanTag());
1002 removeUnknownDmacFlow(dpId, elanInfo);
1003 removeElanBroadcastGroup(elanInfo, interfaceInfo);
1004 removeLocalBroadcastGroup(elanInfo, interfaceInfo);
1005 if ( elanInfo.getVni() != null && elanInfo.getVni().longValue() != 0 ) {
1006 unsetExternalTunnelTable(dpId, elanInfo);
1008 removeFilterEqualsTable(elanInfo, interfaceInfo);
1010 setupElanBroadcastGroups(elanInfo, interfaceInfo);
1011 setupLocalBroadcastGroups(elanInfo, interfaceInfo);
1012 removeFilterEqualsTable(elanInfo, interfaceInfo);
1016 private void removeUnknownDmacFlow(BigInteger dpId, ElanInstance elanInfo) {
1017 // Flow flow = getUnknownDmacFlowEntity(dpId, elanInfo);
1018 // mdsalManager.removeFlow(dpId, flow);
1019 Flow flow = new FlowBuilder().setId(new FlowId(getUnknownDmacFlowRef(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE,
1020 elanInfo.getElanTag(), /*SH flag*/ false)))
1021 .setTableId(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE)
1023 mdsalManager.removeFlow(dpId, flow);
1025 if ( elanInfo.getVni() != null && elanInfo.getVni() > 0 ) {
1026 Flow flow2 = new FlowBuilder().setId(new FlowId(getUnknownDmacFlowRef(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE,
1027 elanInfo.getElanTag(), /*SH flag*/ true)))
1028 .setTableId(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE)
1030 mdsalManager.removeFlow(dpId, flow2);
1036 private void removeDefaultTermFlow(BigInteger dpId, long elanTag) {
1037 ElanUtils.removeTerminatingServiceAction(dpId, (int) elanTag);
1040 private void bindService(ElanInstance elanInfo, String interfaceName) {
1041 // interfaceManager.bindService(interfaceName, ElanUtils.getServiceInfo(elanInfo.getElanInstanceName(), elanInfo.getElanTag(), interfaceName));
1043 int priority = ElanConstants.ELAN_SERVICE_PRIORITY;
1044 int instructionKey = 0;
1045 List<Instruction> instructions = new ArrayList<Instruction>();
1046 instructions.add(MDSALUtil.buildAndGetWriteMetadaInstruction(ElanUtils.getElanMetadataLabel(elanInfo.getElanTag()), MetaDataUtil.METADATA_MASK_SERVICE, ++instructionKey));
1047 instructions.add(MDSALUtil.buildAndGetGotoTableInstruction(ElanConstants.ELAN_SMAC_TABLE, ++instructionKey));
1050 ElanUtils.getBoundServices(String.format("%s.%s.%s", "vpn",elanInfo.getElanInstanceName(), interfaceName),
1051 ElanConstants.ELAN_SERVICE_INDEX, priority,
1052 ElanConstants.COOKIE_ELAN_INGRESS_TABLE, instructions);
1053 ElanUtils.syncWrite(broker, LogicalDatastoreType.CONFIGURATION,
1054 ElanUtils.buildServiceId(interfaceName, ElanConstants.ELAN_SERVICE_INDEX), serviceInfo);
1057 private void unbindService(ElanInstance elanInfo, String interfaceName) {
1058 ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION,
1059 ElanUtils.buildServiceId(interfaceName,ElanConstants.ELAN_SERVICE_INDEX),
1060 ElanUtils.DEFAULT_CALLBACK);
1063 private void unbindService(ElanInstance elanInfo, String interfaceName, int vlanId) {
1064 ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION,
1065 ElanUtils.buildServiceId(interfaceName,ElanConstants.ELAN_SERVICE_INDEX),
1066 ElanUtils.DEFAULT_CALLBACK);
1069 private String getFlowRef(long tableId, long elanTag) {
1070 return new StringBuffer().append(tableId).append(elanTag).toString();
1073 private String getUnknownDmacFlowRef(long tableId, long elanTag, boolean shFlag) {
1074 return new StringBuffer().append(tableId).append(elanTag).append(shFlag).toString();
1077 private List<Action> getInterfacePortActions(InterfaceInfo interfaceInfo) {
1078 List<Action> listAction = new ArrayList<Action>();
1080 listAction.add((new ActionInfo(ActionType.set_field_tunnel_id, new BigInteger[] {BigInteger.valueOf(interfaceInfo.getInterfaceTag())}, actionKey)).buildAction());
1082 listAction.add((new ActionInfo(ActionType.nx_resubmit,
1083 new String[] {String.valueOf(ElanConstants.ELAN_FILTER_EQUALS_TABLE)}, actionKey)).buildAction());
1087 private void updateElanDpnInterfacesList(String elanInstanceName, BigInteger dpId, List<String> interfaceNames) {
1088 DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId)
1089 .setInterfaces(interfaceNames).setKey(new DpnInterfacesKey(dpId)).build();
1090 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId),
1095 * Delete elan dpn interface from operational DS.
1097 * @param elanInstanceName
1098 * the elan instance name
1102 private void deleteElanDpnInterface(String elanInstanceName, BigInteger dpId) {
1103 MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL,
1104 ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId));
1107 private List<String> createElanInterfacesList(String elanInstanceName, String interfaceName, BigInteger dpId) {
1108 List<String> interfaceNames = new ArrayList<String>();
1109 interfaceNames.add(interfaceName);
1110 DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId)
1111 .setInterfaces(interfaceNames).setKey(new DpnInterfacesKey(dpId)).build();
1112 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId),
1114 return interfaceNames;
1117 private void createElanInterfaceTablesList(String interfaceName) {
1118 InstanceIdentifier<ElanInterfaceMac> elanInterfaceMacTables = ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName);
1119 Optional<ElanInterfaceMac> interfaceMacTables = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanInterfaceMacTables);
1120 // Adding new Elan Interface Port to the operational DataStore without Static-Mac Entries..
1121 if(!interfaceMacTables.isPresent()) {
1122 ElanInterfaceMac elanInterfaceMacTable = new ElanInterfaceMacBuilder().setElanInterface(interfaceName).setKey(new ElanInterfaceMacKey(interfaceName)).build();
1123 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName),
1124 elanInterfaceMacTable);
1128 private void createElanStateList(String elanInstanceName, String interfaceName) {
1129 InstanceIdentifier<Elan> elanInstance = ElanUtils.getElanInstanceOperationalDataPath(elanInstanceName);
1130 Optional<Elan> elanInterfaceLists = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanInstance);
1131 // Adding new Elan Interface Port to the operational DataStore without Static-Mac Entries..
1132 if(elanInterfaceLists.isPresent()) {
1133 List<String> interfaceLists = elanInterfaceLists.get().getElanInterfaces();
1134 if(interfaceLists == null) {
1135 interfaceLists = new ArrayList<>();
1137 interfaceLists.add(interfaceName);
1138 Elan elanState = new ElanBuilder().setName(elanInstanceName).setElanInterfaces(interfaceLists).setKey(new ElanKey(elanInstanceName)).build();
1139 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanInstanceName), elanState);
1143 private boolean isOperational(InterfaceInfo interfaceInfo) {
1144 if (interfaceInfo == null) {
1147 return ((interfaceInfo.getOpState() == InterfaceInfo.InterfaceOpState.UP) && (interfaceInfo.getAdminState() == InterfaceInfo.InterfaceAdminState.ENABLED));
1150 protected void updatedIfPrimaryAttributeChanged(ElanInterface elanInterface, boolean isUpdated) {
1151 String interfaceName = elanInterface.getName();
1152 InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
1153 BigInteger dpId = interfaceInfo.getDpId();
1154 InstanceIdentifier<ElanInterfaceMac> elanInterfaceId = ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName);
1155 Optional<ElanInterfaceMac> existingElanInterface = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanInterfaceId);
1156 ElanInstance elanInfo = ElanUtils.getElanInstanceByName(elanInterface.getElanInstanceName());
1158 if(!existingElanInterface.isPresent()) {
1162 List<MacEntry> macEntries = existingElanInterface.get().getMacEntry();
1163 if(macEntries != null && !macEntries.isEmpty()) {
1164 for (MacEntry macEntry : macEntries) {
1166 ElanUtils.setupMacFlows(elanInfo, interfaceInfo, ElanConstants.STATIC_MAC_TIMEOUT, macEntry.getMacAddress().getValue());
1168 ElanUtils.deleteMacFlows(elanInfo, interfaceInfo, macEntry);
1173 InstanceIdentifier<DpnInterfaces> dpnInterfaceId = ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInterface.getElanInstanceName(), interfaceInfo.getDpId());
1174 Optional<DpnInterfaces> dpnInterfaces = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, dpnInterfaceId);
1175 List<String> interfaceLists = dpnInterfaces.get().getInterfaces();
1178 interfaceLists.add(elanInterface.getName());
1180 interfaceLists.remove(elanInterface.getName());
1183 DpnInterfaces updateDpnInterfaces = new DpnInterfacesBuilder().setInterfaces(interfaceLists).setDpId(dpId).setKey(new DpnInterfacesKey(dpId)).build();
1184 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, dpnInterfaceId, updateDpnInterfaces);
1187 installFlowsAndGroups(elanInfo, interfaceInfo);
1189 removeStaticELanFlows(elanInfo, interfaceInfo);
1190 unbindService(elanInfo, interfaceName);
1194 public void handleTunnelStateEvent(BigInteger srcDpId, BigInteger dstDpId) {
1195 ElanDpnInterfaces dpnInterfaceLists = ElanUtils.getElanDpnInterfacesList();
1196 Set<String> elanInstancesMap = new HashSet<>();
1197 if(dpnInterfaceLists == null) {
1200 List<ElanDpnInterfacesList> elanDpnIf = dpnInterfaceLists.getElanDpnInterfacesList();
1201 for(ElanDpnInterfacesList elanDpns: elanDpnIf) {
1203 String elanName = elanDpns.getElanInstanceName();
1204 List<DpnInterfaces> dpnInterfaces = elanDpns.getDpnInterfaces();
1205 if(dpnInterfaces == null) {
1208 for (DpnInterfaces dpnIf : dpnInterfaces) {
1209 if(dpnIf.getDpId().equals(srcDpId) || dpnIf.getDpId().equals(dstDpId)) {
1214 logger.debug("Elan instance:{} is present b/w srcDpn:{} and dstDpn:{}", elanName, srcDpId, dstDpId);
1215 DpnInterfaces dpnInterface = ElanUtils.getElanInterfaceInfoByElanDpn(elanName, srcDpId);
1216 Set<String> interfaceLists = new HashSet<>();
1217 ElanInstance elanInfo = ElanUtils.getElanInstanceByName(elanName);
1218 interfaceLists.addAll(dpnInterface.getInterfaces());
1219 for(String ifName : interfaceLists) {
1220 InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(ifName);
1221 if (isOperational(interfaceInfo)) {
1222 if (interfaceInfo.getDpId().equals(srcDpId) && !elanInstancesMap.contains(elanDpns.getElanInstanceName())) {
1223 elanInstancesMap.add(elanDpns.getElanInstanceName());
1224 elanInterfaceManager.updateRemoteBCGrouponDpnTunnelEvent(elanInfo, interfaceInfo, dstDpId);
1226 elanInterfaceManager.installDMacAddressTables(elanInfo, interfaceInfo, dstDpId);
1234 public void handleInterfaceUpdated(InterfaceInfo interfaceInfo, ElanInstance elanInstance, boolean isStateUp) {
1235 BigInteger dpId = interfaceInfo.getDpId();
1236 String elanName = elanInstance.getElanInstanceName();
1237 String ifName = interfaceInfo.getInterfaceName();
1238 logger.trace("Handling interface update event for interface with info {} , state {}", interfaceInfo, isStateUp);
1241 DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanName, dpId);
1242 if(dpnInterfaces == null) {
1243 createElanInterfacesList(elanName, interfaceInfo.getInterfaceName(), dpId);
1245 List<String> dpnElanInterfaces = dpnInterfaces.getInterfaces();
1246 dpnElanInterfaces.add(interfaceInfo.getInterfaceName());
1247 DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId)
1248 .setInterfaces(dpnElanInterfaces).setKey(new DpnInterfacesKey(dpId)).build();
1249 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanName, interfaceInfo.getDpId()), dpnInterface);
1252 logger.trace("ElanInterface Service is installed for interface:{}", ifName);
1253 elanInterfaceManager.installFlowsAndGroups(elanInstance, interfaceInfo);
1254 elanInterfaceManager.installMacAddressTables(elanInstance, interfaceInfo);
1257 DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanName, dpId);
1258 if(dpnInterfaces != null) {
1259 List<String> dpnElanInterfaces = dpnInterfaces.getInterfaces();
1260 dpnElanInterfaces.remove(interfaceInfo.getInterfaceName());
1261 DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId)
1262 .setInterfaces(dpnElanInterfaces).setKey(new DpnInterfacesKey(dpId)).build();
1263 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanName, interfaceInfo.getDpId()), dpnInterface);
1265 logger.trace("ElanInterface Service is removed for the interface:{}", ifName);
1266 elanInterfaceManager.removeMacAddressTables(elanInstance, interfaceInfo);
1267 elanInterfaceManager.removeFlowsAndGroups(elanInstance, interfaceInfo);
1269 // Removing MACs from External Devices belonging to this ELAN
1270 if (elanInstance.getVni() != null && elanInstance.getVni() != 0) {
1271 List<PhysAddress> macAddresses = ElanUtils
1272 .getElanInterfaceMacAddresses(interfaceInfo.getInterfaceName());
1273 if (macAddresses != null && !macAddresses.isEmpty()) {
1274 ElanL2GatewayUtils.removeMacsFromElanExternalDevices(elanInstance, macAddresses);
1280 private List<MatchInfo> getMatchesForFilterEqualsLPortTag(int LportTag) {
1281 List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
1282 // Matching metadata
1283 mkMatches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
1284 MetaDataUtil.getLportTagMetaData(LportTag),
1285 MetaDataUtil.METADATA_MASK_LPORT_TAG }));
1286 mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[] {BigInteger.valueOf(LportTag)}));
1291 private List<MatchInfo> getTunnelIdMatchForFilterEqualsLPortTag(int LportTag) {
1292 List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
1293 // Matching metadata
1294 mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[] {
1295 BigInteger.valueOf(LportTag)}));
1299 public void updateElanBroadcastGroup(ElanInstance elanInfo) {
1301 long groupId = ElanUtils.getElanRemoteBCGID(elanInfo.getElanTag());
1303 List<DpnInterfaces> dpns = ElanUtils.getInvolvedDpnsInElan(elanInfo
1304 .getElanInstanceName());
1308 for (DpnInterfaces dpn : dpns) {
1310 List<Bucket> listBucket = new ArrayList<Bucket>();
1311 bucketId = getLocalBcGroupBuckets(dpn, listBucket, bucketId);
1312 getRemoteBCGroupBuckets(elanInfo, dpn.getDpId(), listBucket,
1314 Group group = MDSALUtil.buildGroup(groupId,
1315 elanInfo.getElanInstanceName(), GroupTypes.GroupAll,
1316 MDSALUtil.buildBucketLists(listBucket));
1317 logger.trace("installing the localBroadCast Group:{}", group);
1318 mdsalManager.syncInstallGroup(dpn.getDpId(), group,
1319 ElanConstants.DELAY_TIME_IN_MILLISECOND);
1323 private int getLocalBcGroupBuckets(DpnInterfaces dpn,
1324 List<Bucket> listBucket, int bucketId) {
1325 for (String intf : dpn.getInterfaces()) {
1326 InterfaceInfo ifInfo = interfaceManager.getInterfaceInfo(intf);
1327 if (!isOperational(ifInfo)) {
1330 listBucket.add(MDSALUtil.buildBucket(
1331 getInterfacePortActions(ifInfo), MDSALUtil.GROUP_WEIGHT,
1332 bucketId, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
1338 private void getRemoteBCGroupBuckets(ElanInstance elanInfo,
1339 BigInteger dpnId, List<Bucket> listBucket, int bucketId) {
1340 int elanTag = elanInfo.getElanTag().intValue();
1341 ElanDpnInterfacesList elanDpns = ElanUtils
1342 .getElanDpnInterfacesList(elanInfo.getElanInstanceName());
1343 if (elanDpns != null) {
1344 List<DpnInterfaces> dpnInterfaceses = elanDpns.getDpnInterfaces();
1345 for (DpnInterfaces dpnInterface : dpnInterfaceses) {
1346 if (ElanUtils.isDpnPresent(dpnInterface.getDpId())
1347 && dpnInterface.getDpId() != dpnId
1348 && dpnInterface.getInterfaces() != null
1349 && !dpnInterface.getInterfaces().isEmpty()) {
1351 List<Action> listActionInfo = ElanUtils
1352 .getInternalItmEgressAction(dpnId,
1353 dpnInterface.getDpId(), elanTag);
1354 listBucket.add(MDSALUtil.buildBucket(listActionInfo, 0,
1355 bucketId, 0xffffffffL, 0xffffffffL));
1357 } catch (Exception ex) {
1359 "Logical Group Interface not found between source Dpn - {}, destination Dpn - {} ",
1360 dpnId, dpnInterface.getDpId());
1365 List<Bucket> elanL2GwDevicesBuckets = getRemoteBCGroupBucketsOfElanL2GwDevices(elanInfo, dpnId, bucketId);
1366 listBucket.addAll(elanL2GwDevicesBuckets);
1369 public static List<Bucket> getRemoteBCGroupBucketsOfElanL2GwDevices(ElanInstance elanInfo, BigInteger dpnId,
1371 List<Bucket> listBucketInfo = new ArrayList<Bucket>();
1372 ConcurrentMap<String, L2GatewayDevice> map = ElanL2GwCacheUtils
1373 .getAllElanL2GatewayDevicesFromCache(elanInfo.getElanInstanceName());
1374 for (L2GatewayDevice device : map.values()) {
1375 String interfaceName = ElanL2GatewayUtils.getExternalTunnelInterfaceName(String.valueOf(dpnId),
1376 device.getHwvtepNodeId());
1377 if (interfaceName == null) {
1380 List<Action> listActionInfo = ElanUtils.buildItmEgressActions(interfaceName, elanInfo.getVni());
1381 listBucketInfo.add(MDSALUtil.buildBucket(listActionInfo, MDSALUtil.GROUP_WEIGHT, bucketId,
1382 MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
1385 return listBucketInfo;