2 * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.vpnservice.elan.internal;
10 import com.google.common.base.Optional;
11 import com.google.common.collect.Lists;
12 import com.google.common.collect.Maps;
13 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
14 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
15 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
16 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
17 import org.opendaylight.vpnservice.elan.utils.ElanConstants;
18 import org.opendaylight.vpnservice.elan.utils.ElanConstants;
19 import org.opendaylight.vpnservice.elan.utils.ElanUtils;
20 import org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo;
21 import org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo.InterfaceType;
22 import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
23 import org.opendaylight.vpnservice.itm.api.IITMProvider;
24 import org.opendaylight.vpnservice.itm.globals.ITMConstants;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCase;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.*;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.ExtensionKey;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlow;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlowBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.grouping.ExtensionBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionList;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionListBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.*;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.nx.reg.grouping.NxmNxRegBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.services.info.BoundServices;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
42 import org.opendaylight.vpnservice.mdsalutil.*;
43 import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
44 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.ElanDpnInterfaces;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.ElanForwardingTables;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.ElanInterfaces;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan._interface.forwarding.entries.ElanInterfaceMac;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan._interface.forwarding.entries.ElanInterfaceMacBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan._interface.forwarding.entries.ElanInterfaceMacKey;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesList;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfaces;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfacesBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfacesKey;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.forwarding.tables.MacTable;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.forwarding.tables.MacTableKey;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstance;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstanceBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.interfaces.ElanInterface;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.state.Elan;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.state.ElanBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.state.ElanKey;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntry;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntryBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntryKey;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetEgressActionsForInterfaceInputBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetEgressActionsForInterfaceOutput;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.OdlInterfaceRpcService;
71 import org.opendaylight.yangtools.concepts.ListenerRegistration;
72 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
74 import org.opendaylight.yangtools.yang.common.RpcResult;
75 import org.slf4j.Logger;
76 import org.slf4j.LoggerFactory;
78 import java.math.BigInteger;
80 import java.util.concurrent.ConcurrentHashMap;
81 import java.util.concurrent.ConcurrentLinkedQueue;
82 import java.util.concurrent.ExecutionException;
83 import java.util.concurrent.Future;
86 public class ElanInterfaceManager extends AbstractDataChangeListener<ElanInterface> implements AutoCloseable {
88 private static ElanInterfaceManager elanInterfaceManager = new ElanInterfaceManager();
89 private ListenerRegistration<DataChangeListener> elanInterfaceListenerRegistration;
90 private ListenerRegistration<DataChangeListener> itmInterfaceListenerRegistration;
91 private OdlInterfaceRpcService interfaceManagerRpcService;
92 private DataBroker broker;
93 private IMdsalApiManager mdsalManager;
94 private IInterfaceManager interfaceManager;
95 private IdManagerService idManager;
96 private IITMProvider itmManager;
97 private ElanForwardingEntriesHandler elanForwardingEntriesHandler;
98 private Map<String, ConcurrentLinkedQueue<ElanInterface>> unProcessedElanInterfaces =
99 new ConcurrentHashMap<String, ConcurrentLinkedQueue<ElanInterface>> ();
101 private static final Logger logger = LoggerFactory.getLogger(ElanInterfaceManager.class);
103 public ElanInterfaceManager() {
104 super(ElanInterface.class);
107 public static ElanInterfaceManager getElanInterfaceManager() {
108 return elanInterfaceManager;
111 public void setMdSalApiManager(IMdsalApiManager mdsalManager) {
112 this.mdsalManager = mdsalManager;
115 public void setInterfaceManagerRpcService(OdlInterfaceRpcService ifManager) {
116 this.interfaceManagerRpcService = ifManager;
119 public void setElanForwardingEntriesHandler(ElanForwardingEntriesHandler elanForwardingEntriesHandler) {
120 this.elanForwardingEntriesHandler = elanForwardingEntriesHandler;
123 public void setInterfaceManager(IInterfaceManager interfaceManager) {
124 this.interfaceManager = interfaceManager;
127 public void setDataBroker(DataBroker broker) {
128 this.broker = broker;
131 public void setIITMManager(IITMProvider itmManager) {
132 this.itmManager = itmManager;
136 public void close() throws Exception {
137 if (elanInterfaceListenerRegistration != null) {
139 elanInterfaceListenerRegistration.close();
140 } catch (final Exception e) {
141 logger.error("Error when cleaning up DataChangeListener.", e);
143 elanInterfaceListenerRegistration = null;
147 public void registerListener() {
149 elanInterfaceListenerRegistration = broker.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
150 getElanInterfaceWildcardPath(), ElanInterfaceManager.this, DataChangeScope.SUBTREE);
151 } catch (final Exception e) {
152 logger.error("ELAN Interface DataChange listener registration failed !", e);
153 throw new IllegalStateException("ELAN Interface registration Listener failed.", e);
157 private InstanceIdentifier<?> getElanInterfaceWildcardPath() {
158 return InstanceIdentifier.create(ElanInterfaces.class).child(ElanInterface.class);
161 public void setIdManager(IdManagerService idManager) {
162 this.idManager = idManager;
166 protected void remove(InstanceIdentifier<ElanInterface> identifier, ElanInterface del) {
167 String interfaceName = del.getName();
168 ElanInstance elanInfo = ElanUtils.getElanInstanceByName(del.getElanInstanceName());
169 removeElanInterface(elanInfo, interfaceName);
172 public void removeElanService(ElanInterface del, int vlanId) {
173 ElanInstance elanInstance = ElanUtils.getElanInstanceByName(del.getElanInstanceName());
174 String interfaceName = del.getName();
175 InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfoFromOperationalDataStore(interfaceName, InterfaceType.VLAN_INTERFACE);
176 removeElanInterface(elanInstance, interfaceInfo);
177 unbindService(elanInstance, interfaceName, vlanId);
180 public void removeElanInterface(ElanInstance elanInfo, String interfaceName) {
181 String elanName = elanInfo.getElanInstanceName();
182 InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
183 if (interfaceInfo == null) {
184 ElanInterfaceMac elanInterfaceMac = ElanUtils.getElanInterfaceMacByInterfaceName(interfaceName);
185 if(elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null) {
186 List<MacEntry> macEntries = elanInterfaceMac.getMacEntry();
187 for(MacEntry macEntry : macEntries) {
188 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getMacEntryOperationalDataPath(elanName, macEntry.getMacAddress()));
191 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName));
192 Elan elanState = ElanUtils.getElanByName(elanName);
193 List<String> elanInterfaces = elanState.getElanInterfaces();
194 elanInterfaces.remove(interfaceName);
195 if(elanInterfaces.isEmpty()) {
196 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanName));
197 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanMacTableOperationalDataPath(elanName));
198 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInfoEntriesOperationalDataPath(elanInfo.getElanTag()));
199 ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION, ElanUtils.getElanInstanceConfigurationDataPath(elanName));
201 Elan updateElanState = new ElanBuilder().setElanInterfaces(elanInterfaces).setName(elanName).setKey(new ElanKey(elanName)).build();
202 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanName), updateElanState);
206 removeElanInterface(elanInfo, interfaceInfo);
207 unbindService(elanInfo, interfaceName);
210 private void removeElanInterface(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
212 BigInteger dpId = interfaceInfo.getDpId();
213 String elanName = elanInfo.getElanInstanceName();
214 String interfaceName = interfaceInfo.getInterfaceName();
215 Elan elanState = ElanUtils.getElanByName(elanName);
216 logger.debug("Removing the Interface:{} from elan:{}", interfaceName, elanName);
217 InstanceIdentifier<ElanInterfaceMac> elanInterfaceId = ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName);
218 Optional<ElanInterfaceMac> existingElanInterface = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanInterfaceId);
219 if(existingElanInterface.isPresent()) {
220 List<MacEntry> macEntries = existingElanInterface.get().getMacEntry();
221 if(macEntries != null && !macEntries.isEmpty()) {
222 for (MacEntry macEntry : macEntries) {
223 logger.debug("removing the mac-entry:{} present on elanInterface:{}", macEntry.getMacAddress().getValue(), interfaceName);
224 elanForwardingEntriesHandler.deleteElanInterfaceForwardingEntries(elanInfo, interfaceInfo, macEntry);
230 *This condition check is mainly to get DPN-ID in pre-provision deletion scenario after stopping CSS
232 if(dpId.equals(ElanConstants.INVALID_DPN)) {
233 ElanDpnInterfacesList elanDpnInterfacesList = ElanUtils.getElanDpnInterfacesList(elanName);
234 if(elanDpnInterfacesList != null && !elanDpnInterfacesList.getDpnInterfaces().isEmpty()) {
235 List<DpnInterfaces> dpnIfList = elanDpnInterfacesList.getDpnInterfaces();
236 for (DpnInterfaces dpnInterface : dpnIfList) {
237 DpnInterfaces dpnIfLists = ElanUtils.getElanInterfaceInfoByElanDpn(elanName, dpnInterface.getDpId());
238 if (dpnIfLists.getInterfaces().contains(interfaceName)) {
239 logger.debug("deleting the elanInterface from the ElanDpnInterface cache in pre-provision scenario of elan:{} dpn:{} interfaceName:{}", elanName, dpId, interfaceName);
240 removeElanDpnInterfaceFromOperationalDataStore(elanName, dpId, interfaceName);
246 removeElanDpnInterfaceFromOperationalDataStore(elanName, dpId, interfaceName);
249 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, elanInterfaceId);
250 List<String> elanInterfaces = elanState.getElanInterfaces();
251 elanInterfaces.remove(interfaceName);
252 removeStaticELanFlows(elanInfo, interfaceInfo);
253 if(elanInterfaces.isEmpty()) {
254 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanName));
255 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnOperationDataPath(elanName));
256 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanMacTableOperationalDataPath(elanName));
257 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInfoEntriesOperationalDataPath(elanInfo.getElanTag()));
258 //ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION, ElanUtils.getElanInstanceConfigurationDataPath(elanName));
260 Elan updateElanState = new ElanBuilder().setElanInterfaces(elanInterfaces).setName(elanName).setKey(new ElanKey(elanName)).build();
261 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanName), updateElanState);
265 private void removeElanDpnInterfaceFromOperationalDataStore(String elanName, BigInteger dpId, String interfaceName) {
266 DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanName, dpId);
267 if(dpnInterfaces != null) {
268 List<String> interfaceLists = dpnInterfaces.getInterfaces();
269 interfaceLists.remove(interfaceName);
270 updateElanDpnInterfacesList(elanName, dpId, interfaceLists);
275 protected void update(InstanceIdentifier<ElanInterface> identifier, ElanInterface original, ElanInterface update) {
276 // updating the static-Mac Entries for the existing elanInterface
277 String elanName = update.getElanInstanceName();
278 String interfaceName = update.getName();
279 InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
280 List<PhysAddress> existingPhysAddress = original.getStaticMacEntries();
281 List<PhysAddress> updatedPhysAddress = update.getStaticMacEntries();
282 if(updatedPhysAddress != null && !updatedPhysAddress.isEmpty()) {
283 List<PhysAddress> existingClonedPhyAddress = new ArrayList<>();
284 if(existingPhysAddress != null && !existingPhysAddress.isEmpty()) {
285 existingClonedPhyAddress.addAll(0, existingPhysAddress);
286 existingPhysAddress.removeAll(updatedPhysAddress);
287 updatedPhysAddress.removeAll(existingClonedPhyAddress);
288 // removing the PhyAddress which are not presented in the updated List
289 for(PhysAddress physAddress: existingPhysAddress) {
290 removeInterfaceStaticMacEntires(elanName, interfaceName, physAddress);
293 // Adding the new PhysAddress which are presented in the updated List
294 if(updatedPhysAddress.size() > 0) {
295 for(PhysAddress physAddress: updatedPhysAddress) {
296 InstanceIdentifier<MacEntry> macId = getMacEntryOperationalDataPath(elanName, physAddress);
297 Optional<MacEntry> existingMacEntry = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, macId);
298 if(existingMacEntry.isPresent()) {
299 elanForwardingEntriesHandler.updateElanInterfaceForwardingTablesList(elanName, interfaceName, existingMacEntry.get().getInterface(), existingMacEntry.get());
301 elanForwardingEntriesHandler.addElanInterfaceForwardingTableList(ElanUtils.getElanInstanceByName(elanName), interfaceName, physAddress);
305 } else if(existingPhysAddress != null && !existingPhysAddress.isEmpty()) {
306 for( PhysAddress physAddress : existingPhysAddress) {
307 removeInterfaceStaticMacEntires(elanName, interfaceName, physAddress);
313 protected void add(InstanceIdentifier<ElanInterface> identifier, ElanInterface elanInterfaceAdded) {
314 String elanInstanceName = elanInterfaceAdded.getElanInstanceName();
315 String interfaceName = elanInterfaceAdded.getName();
316 InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
317 ElanInstance elanInstance = ElanUtils.getElanInstanceByName(elanInstanceName);
319 if (elanInstance == null) {
320 elanInstance = new ElanInstanceBuilder().setElanInstanceName(elanInstanceName).setDescription(elanInterfaceAdded.getDescription()).build();
321 //Add the ElanInstance in the Configuration data-store
322 ElanUtils.UpdateOperationalDataStore(broker, idManager, elanInstance);
323 elanInstance = ElanUtils.getElanInstanceByName(elanInstanceName);
327 Long elanTag = elanInstance.getElanTag();
328 // If elan tag is not updated, then put the elan interface into unprocessed entry map and entry. Let entries
329 // in this map get processed during ELAN update DCN.
330 if (elanTag == null) {
331 ConcurrentLinkedQueue<ElanInterface> elanInterfaces = unProcessedElanInterfaces.get(elanInstanceName);
332 if (elanInterfaces == null) {
333 elanInterfaces = new ConcurrentLinkedQueue<ElanInterface>();
335 elanInterfaces.add(elanInterfaceAdded);
336 unProcessedElanInterfaces.put(elanInstanceName, elanInterfaces);
339 addElanInterface(elanInterfaceAdded, interfaceInfo, elanInstance);
342 void handleunprocessedElanInterfaces(ElanInstance elanInstance) {
343 Queue<ElanInterface> elanInterfaces = unProcessedElanInterfaces.get(elanInstance.getElanInstanceName());
344 if (elanInterfaces == null || elanInterfaces.isEmpty()) {
347 for (ElanInterface elanInterface: elanInterfaces) {
348 String interfaceName = elanInterface.getName();
349 InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
350 addElanInterface(elanInterface, interfaceInfo, elanInstance);
354 void addElanInterface(ElanInterface elanInterface, InterfaceInfo interfaceInfo, ElanInstance elanInstance) {
355 String interfaceName = elanInterface.getName();
356 String elanInstanceName = elanInterface.getElanInstanceName();
357 List<PhysAddress> staticMacAddresses = elanInterface.getStaticMacEntries();
358 Elan elanInfo = ElanUtils.getElanByName(elanInstanceName);
359 BigInteger dpId = null;
360 if(elanInfo == null) {
361 ElanUtils.UpdateOperationalDataStore(broker, idManager, elanInstance);
363 if(interfaceInfo != null) {
364 dpId = interfaceInfo.getDpId();
366 if(dpId != null && !dpId.equals(ElanConstants.INVALID_DPN)) {
367 InstanceIdentifier<DpnInterfaces> elanDpnInterfaces = ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId);
368 Optional<DpnInterfaces> existingElanDpnInterfaces = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanDpnInterfaces);
369 if (!existingElanDpnInterfaces.isPresent()) {
370 createElanInterfacesList(elanInstanceName, interfaceName, dpId);
372 List<String> elanInterfaces = existingElanDpnInterfaces.get().getInterfaces();
373 elanInterfaces.add(interfaceName);
374 updateElanDpnInterfacesList(elanInstanceName, dpId, elanInterfaces);
378 // add code to install Local/Remote BC group, unknow DMAC entry, terminating service table flow entry
379 // call bindservice of interfacemanager to create ingress table flow enty.
380 //Add interface to the ElanInterfaceForwardingEntires Container
381 createElanInterfaceTablesList(interfaceName);
382 createElanStateList(elanInstanceName, interfaceName);
383 if(interfaceInfo != null) {
384 installFlowsAndGroups(elanInstance, interfaceInfo);
386 // add the static mac addresses
387 if(staticMacAddresses != null) {
388 for (PhysAddress physAddress : staticMacAddresses) {
389 InstanceIdentifier<MacEntry> macId = getMacEntryOperationalDataPath(elanInstanceName, physAddress);
390 Optional<MacEntry> existingMacEntry = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, macId);
391 if (existingMacEntry.isPresent()) {
392 elanForwardingEntriesHandler.updateElanInterfaceForwardingTablesList(elanInstanceName, interfaceName, existingMacEntry.get().getInterface(), existingMacEntry.get());
394 elanForwardingEntriesHandler.addElanInterfaceForwardingTableList(elanInstance, interfaceName, physAddress);
396 if(interfaceInfo != null && isOperational(interfaceInfo)) {
397 logger.debug("Installing Static Mac-Entry on the Elan Interface:{} with MacAddress:{}", interfaceInfo, physAddress.getValue());
398 ElanUtils.setupMacFlows(elanInstance, interfaceInfo, ElanConstants.STATIC_MAC_TIMEOUT, physAddress.getValue());
404 private Map<BigInteger, List<String>> readFePortsDbForElan(String elanName) {
405 ElanDpnInterfacesList elanDpnInterfacesList = ElanUtils.getElanDpnInterfacesList(elanName);
406 HashMap<BigInteger, List<String>> fePortsDb = Maps.newHashMap();
407 if (elanDpnInterfacesList == null) {
410 List<DpnInterfaces> dpnInterfaces = elanDpnInterfacesList.getDpnInterfaces();
411 if (dpnInterfaces == null) {
414 for (DpnInterfaces dpnInterface : dpnInterfaces) {
415 fePortsDb.put(dpnInterface.getDpId(), dpnInterface.getInterfaces());
420 protected void removeInterfaceStaticMacEntires(String elanInstanceName, String interfaceName, PhysAddress physAddress) {
421 InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
422 InstanceIdentifier<MacEntry> macId = getMacEntryOperationalDataPath(elanInstanceName, physAddress);
423 Optional<MacEntry> existingMacEntry = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, macId);
425 if(!existingMacEntry.isPresent()) {
429 MacEntry macEntry = new MacEntryBuilder().setMacAddress(physAddress).setInterface(interfaceName).setKey(new MacEntryKey(physAddress)).build();
430 elanForwardingEntriesHandler.deleteElanInterfaceForwardingEntries(ElanUtils.getElanInstanceByName(elanInstanceName), interfaceInfo, macEntry);
431 elanForwardingEntriesHandler.deleteElanInterfaceMacForwardingEntries(interfaceName, physAddress);
435 private InstanceIdentifier<MacEntry> getMacEntryOperationalDataPath(String elanName, PhysAddress physAddress) {
436 return InstanceIdentifier.builder(ElanForwardingTables.class).child(MacTable.class,
437 new MacTableKey(elanName)).child(MacEntry.class, new MacEntryKey(physAddress)).build();
440 public void installFlowsAndGroups(final ElanInstance elanInfo, final InterfaceInfo interfaceInfo) {
441 if (isOperational(interfaceInfo)) {
443 // LocalBroadcast Group creation with elan-Interfaces
444 setupLocalBroadcastGroups(elanInfo, interfaceInfo);
446 //Remote-broadcast group & Terminating Service , UnknownDMAC Table.
447 //setupRemoteBroadcastGroups(elanInfo, interfaceInfo);
448 setupTerminateServiceTable(elanInfo, interfaceInfo);
449 setupUnknownDMacTable(elanInfo, interfaceInfo);
450 setupFilterEqualsTable(elanInfo, interfaceInfo);
451 // bind the Elan service to the Interface
452 bindService(elanInfo, interfaceInfo.getInterfaceName());
454 //update the remote-DPNs remoteBC group entry with Tunnels
455 setRemoteBCGrouponOtherDpns(elanInfo, interfaceInfo);
459 public void setupFilterEqualsTable(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
460 long elanTag = elanInfo.getElanTag();
461 long ifTag = interfaceInfo.getInterfaceTag();
462 List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
463 MatchBuilder mb = new MatchBuilder();
464 addNxRegMatch(mb, RegMatch.of(NxmNxReg1.class, ifTag));
465 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(interfaceInfo.getDpId(), ElanConstants.ELAN_FILTER_EQUALS_TABLE, getFlowRef(ElanConstants.ELAN_FILTER_EQUALS_TABLE, ifTag),
466 9, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_FILTER_EQUALS.add(BigInteger.valueOf(ifTag)), getMatchesForFilterEqualsReg1LPortTag(ifTag),
467 getInstructionsInPortForOutGroup(interfaceInfo.getInterfaceName()));
469 mdsalManager.installFlow(flowEntity);
471 FlowEntity flowEntity1 = MDSALUtil.buildFlowEntity(interfaceInfo.getDpId(), ElanConstants.ELAN_FILTER_EQUALS_TABLE, getFlowRef(ElanConstants.ELAN_FILTER_EQUALS_TABLE, 1000+ifTag),
472 10, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_FILTER_EQUALS.add(BigInteger.valueOf(ifTag)), getMatchesForFilterEqualsLPortTag(ifTag),
473 getInstructionsDrop());
475 mdsalManager.installFlow(flowEntity1);
479 protected List<ActionInfo> getEgressActionsForInterface(String ifName) {
480 List<ActionInfo> listActionInfo = new ArrayList<ActionInfo>();
482 Future<RpcResult<GetEgressActionsForInterfaceOutput>> result =
483 interfaceManagerRpcService.getEgressActionsForInterface(
484 new GetEgressActionsForInterfaceInputBuilder().setIntfName(ifName).build());
485 RpcResult<GetEgressActionsForInterfaceOutput> rpcResult = result.get();
486 System.out.println("Data is populated");
487 if(!rpcResult.isSuccessful()) {
488 logger.warn("RPC Call to Get egress actions for interface {} returned with Errors {}", ifName, rpcResult.getErrors());
490 List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> actions =
491 rpcResult.getResult().getAction();
492 for (Action action : actions) {
493 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionClass = action.getAction();
494 if (actionClass instanceof OutputActionCase) {
495 System.out.println("Data ");
496 listActionInfo.add(new ActionInfo(ActionType.output,
497 new String[] {((OutputActionCase)actionClass).getOutputAction()
498 .getOutputNodeConnector().getValue()}));
499 } else if (actionClass instanceof PushVlanActionCase) {
500 listActionInfo.add(new ActionInfo(ActionType.push_vlan, new String[] {}));
501 } else if (actionClass instanceof SetFieldCase) {
502 if (((SetFieldCase)actionClass).getSetField().getVlanMatch() != null) {
503 int vlanVid = ((SetFieldCase)actionClass).getSetField().getVlanMatch().getVlanId().getVlanId().getValue();
504 listActionInfo.add(new ActionInfo(ActionType.set_field_vlan_vid,
505 new String[] { Long.toString(vlanVid) }));
510 } catch (InterruptedException | ExecutionException e) {
511 logger.warn("Exception when egress actions for interface {}", ifName, e);
513 return listActionInfo;
517 private List<BucketInfo> getRemoteBCGroupBucketInfos(ElanInstance elanInfo,
518 InterfaceInfo interfaceInfo) {
519 BigInteger dpnId = interfaceInfo.getDpId();
520 int elanTag = elanInfo.getElanTag().intValue();
521 List<BucketInfo> listBucketInfo = new ArrayList<BucketInfo>();
522 ElanDpnInterfacesList elanDpns = ElanUtils.getElanDpnInterfacesList(elanInfo.getElanInstanceName());
523 if(elanDpns != null) {
524 List<DpnInterfaces> dpnInterfaceses = elanDpns.getDpnInterfaces();
525 for(DpnInterfaces dpnInterface : dpnInterfaceses) {
526 if(ElanUtils.isDpnPresent(dpnInterface.getDpId()) && dpnInterface.getDpId() != dpnId && dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty()) {
528 //FIXME [ELANBE] Removing ITM API for now, will need this for multi dpn.
529 //List<ActionInfo> listActionInfo = itmManager.ITMIngressGetActions(dpnId, dpnInterface.getDpId(), (int) elanTag);
530 //listBucketInfo.add(new BucketInfo(listActionInfo));
531 } catch (Exception ex) {
532 logger.error( "Logical Group Interface not found between source Dpn - {}, destination Dpn - {} " ,dpnId, dpnInterface.getDpId() );
537 List<ActionInfo> listActionInfo = new ArrayList<ActionInfo>();
538 listActionInfo.add(new ActionInfo(ActionType.group, new String[] {String.valueOf(ElanUtils.getElanLocalBCGID(elanInfo.getElanTag()))}));
539 listBucketInfo.add(new BucketInfo(listActionInfo));
540 return listBucketInfo;
543 public ActionInfo getReg1ActionInfo(int interfaceTag) {
544 return new ActionInfo(ActionType.set_field_reg, new String[] {String.valueOf(interfaceTag)});
547 private void setRemoteBCGrouponOtherDpns(ElanInstance elanInfo,
548 InterfaceInfo interfaceInfo) {
549 BigInteger dpnId = interfaceInfo.getDpId();
550 int elanTag = elanInfo.getElanTag().intValue();
551 long groupId = ElanUtils.getElanRemoteBCGID(elanTag);
552 ElanDpnInterfacesList elanDpns = ElanUtils.getElanDpnInterfacesList(elanInfo.getElanInstanceName());
553 if(elanDpns != null) {
554 List<DpnInterfaces> dpnInterfaceses = elanDpns.getDpnInterfaces();
555 for(DpnInterfaces dpnInterface : dpnInterfaceses) {
556 List<BucketInfo> remoteListBucketInfo = new ArrayList<BucketInfo>();
557 if(ElanUtils.isDpnPresent(dpnInterface.getDpId()) && !dpnInterface.getDpId().equals(dpnId) && dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty()) {
558 for(DpnInterfaces otherFes : dpnInterfaceses) {
559 if (ElanUtils.isDpnPresent(otherFes.getDpId()) && otherFes.getDpId() != dpnInterface.getDpId()
560 && otherFes.getInterfaces() != null && ! otherFes.getInterfaces().isEmpty()) {
562 //FIXME [ELANBE] Removing ITM API for now, will need this for multi dpn.
563 //List<ActionInfo> remoteListActionInfo = itmManager.ITMIngressGetActions(dpnInterface.getDpId(), otherFes.getDpId(), (int) elanTag);
564 //remoteListBucketInfo.add(new BucketInfo(remoteListActionInfo));
565 } catch (Exception ex) {
566 logger.error( "Logical Group Interface not found between source Dpn - {}, destination Dpn - {} " ,dpnInterface.getDpId(), otherFes.getDpId() );
571 List<ActionInfo> remoteListActionInfo = new ArrayList<ActionInfo>();
572 remoteListActionInfo.add(new ActionInfo(ActionType.group, new String[] {String.valueOf(ElanUtils.getElanLocalBCGID(elanTag))}));
573 remoteListBucketInfo.add(new BucketInfo(remoteListActionInfo));
574 GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnInterface.getDpId(), groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, remoteListBucketInfo);
575 mdsalManager.installGroup(groupEntity);
581 private void updateRemoteBCGrouponDpnTunnelEvent(ElanInstance elanInfo,
582 InterfaceInfo interfaceInfo, BigInteger dstDpId) {
583 int elanTag = elanInfo.getElanTag().intValue();
584 long groupId = ElanUtils.getElanRemoteBCGID(elanTag);
585 List<DpnInterfaces> elanDpns = ElanUtils.getInvolvedDpnsInElan(elanInfo.getElanInstanceName());
586 if(elanDpns != null) {
587 for(DpnInterfaces dpnInterface : elanDpns) {
588 List<BucketInfo> remoteListBucketInfo = new ArrayList<BucketInfo>();
589 if(ElanUtils.isDpnPresent(dstDpId) && dpnInterface.getDpId().equals(dstDpId) && dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty()) {
591 //FIXME [ELANBE] Removing ITM API for now, will need this for multi dpn.
592 //List<ActionInfo> remoteListActionInfo = itmManager.ITMIngressGetActions(interfaceInfo.getDpId(), dstDpId, (int) elanTag);
593 //remoteListBucketInfo.add(new BucketInfo(remoteListActionInfo));
594 } catch (Exception ex) {
595 logger.error( "Logical Group Interface not found between source Dpn - {}, destination Dpn - {} " ,dpnInterface.getDpId(), dstDpId);
598 List<ActionInfo> remoteListActionInfo = new ArrayList<ActionInfo>();
599 remoteListActionInfo.add(new ActionInfo(ActionType.group, new String[] {String.valueOf(ElanUtils.getElanLocalBCGID(elanTag))}));
600 remoteListBucketInfo.add(new BucketInfo(remoteListActionInfo));
601 GroupEntity groupEntity = MDSALUtil.buildGroupEntity(interfaceInfo.getDpId(), groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, remoteListBucketInfo);
602 mdsalManager.installGroup(groupEntity);
611 * Returns the bucket info with the given interface as the only bucket.
613 private List<BucketInfo> getLocalBCGroupBucketInfo(InterfaceInfo interfaceInfo) {
614 return Lists.newArrayList(new BucketInfo(getInterfacePortActionInfos(interfaceInfo)));
617 private List<MatchInfo> getMatchesForElanTag(Long elanTag) {
618 List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
620 mkMatches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
621 ElanUtils.getElanMetadataLabel(elanTag),
622 MetaDataUtil.METADATA_MASK_SERVICE }));
626 private List<InstructionInfo> getInstructionsForOutGroup(
628 List<InstructionInfo> mkInstructions = new ArrayList<InstructionInfo>();
629 List <ActionInfo> actionsInfos = new ArrayList <ActionInfo> ();
630 actionsInfos.add(new ActionInfo(ActionType.group, new String[]{Long.toString(groupId)}));
631 mkInstructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos));
632 return mkInstructions;
635 public void removeFlowsAndGroups(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
636 removeStaticELanFlows(elanInfo, interfaceInfo);
637 unbindService(elanInfo, interfaceInfo.getInterfaceName());
640 public void installMacAddressTables(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
641 String interfaceName = interfaceInfo.getInterfaceName();
642 BigInteger currentDpn = interfaceInfo.getDpId();
643 ElanInterfaceMac elanInterfaceMac = ElanUtils.getElanInterfaceMacByInterfaceName(interfaceName);
644 if(elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null) {
645 List<MacEntry> macEntries = elanInterfaceMac.getMacEntry();
646 for(MacEntry macEntry : macEntries) {
647 PhysAddress physAddress = macEntry.getMacAddress();
648 ElanUtils.setupMacFlows(elanInfo, interfaceInfo, macEntry.isIsStaticAddress() ? ElanConstants.STATIC_MAC_TIMEOUT : elanInfo.getMacTimeout(), physAddress.getValue());
650 //Programming the remoteDMACFlows
651 ElanDpnInterfacesList elanDpnInterfacesList = ElanUtils.getElanDpnInterfacesList(elanInfo.getElanInstanceName());
652 List<DpnInterfaces> dpnInterfaceLists = elanDpnInterfacesList.getDpnInterfaces();
653 for(DpnInterfaces dpnInterfaces : dpnInterfaceLists){
654 if(dpnInterfaces.getDpId().equals(interfaceInfo.getDpId())) {
657 List<String> remoteElanInterfaces = dpnInterfaces.getInterfaces();
658 for(String remoteIf : remoteElanInterfaces) {
659 ElanInterfaceMac elanIfMac = ElanUtils.getElanInterfaceMacByInterfaceName(remoteIf);
660 InterfaceInfo remoteInterface = interfaceManager.getInterfaceInfo(remoteIf);
661 if(elanIfMac == null) {
664 List<MacEntry> remoteMacEntries = elanIfMac.getMacEntry();
665 if(remoteMacEntries != null) {
666 for (MacEntry macEntry : remoteMacEntries) {
667 PhysAddress physAddress = macEntry.getMacAddress();
668 ElanUtils.setupRemoteDmacFlow(currentDpn, remoteInterface.getDpId(), remoteInterface.getInterfaceTag(), elanInfo.getElanTag(), physAddress.getValue(), elanInfo.getElanInstanceName());
676 // Install DMAC entry on dst DPN
677 public void installDMacAddressTables(ElanInstance elanInfo, InterfaceInfo interfaceInfo, BigInteger dstDpId) {
678 String interfaceName = interfaceInfo.getInterfaceName();
679 ElanInterfaceMac elanInterfaceMac = ElanUtils.getElanInterfaceMacByInterfaceName(interfaceName);
680 if(elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null) {
681 List<MacEntry> macEntries = elanInterfaceMac.getMacEntry();
682 for(MacEntry macEntry : macEntries) {
683 PhysAddress physAddress = macEntry.getMacAddress();
684 ElanUtils.setupDMacFlowonRemoteDpn(elanInfo, interfaceInfo, dstDpId, physAddress.getValue());
689 public void removeMacAddressTables(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
690 ElanInterfaceMac elanInterfaceMac = ElanUtils.getElanInterfaceMacByInterfaceName(interfaceInfo.getInterfaceName());
691 if(elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null) {
692 List<MacEntry> macEntries = elanInterfaceMac.getMacEntry();
693 for(MacEntry macEntry : macEntries) {
694 ElanUtils.deleteMacFlows(elanInfo, interfaceInfo, macEntry);
699 public void setupLocalBroadcastGroups(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
700 List<BucketInfo> listBucketInfo = new ArrayList<BucketInfo>();
701 BigInteger dpnId = interfaceInfo.getDpId();
702 long groupId = ElanUtils.getElanLocalBCGID(elanInfo.getElanTag());
704 DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanInfo.getElanInstanceName(), dpnId);
705 for(String ifName : dpnInterfaces.getInterfaces()) {
706 // In case if there is a InterfacePort in the cache which is not in
707 // operational state, skip processing it
708 InterfaceInfo ifInfo = interfaceManager.getInterfaceInfoFromOperationalDataStore(ifName, interfaceInfo.getInterfaceType());
709 if (!isOperational(ifInfo)) {
713 listBucketInfo.add(new BucketInfo(getInterfacePortActionInfos(ifInfo)));
715 GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, listBucketInfo);
716 logger.trace("installing the localBroadCast GroupEntity:{}", groupEntity);
717 mdsalManager.syncInstallGroup(groupEntity, ElanConstants.DELAY_TIME_IN_MILLISECOND);
720 public void removeLocalBroadcastGroup(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
721 BigInteger dpnId = interfaceInfo.getDpId();
722 long groupId = ElanUtils.getElanLocalBCGID(elanInfo.getElanTag());
724 GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, getLocalBCGroupBucketInfo(interfaceInfo));
725 logger.trace("deleted the localBroadCast GroupEntity:{}", groupEntity);
726 mdsalManager.syncRemoveGroup(groupEntity);
729 public void setupRemoteBroadcastGroups(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
730 List<BucketInfo> listBucketInfo = getRemoteBCGroupBucketInfos(elanInfo, interfaceInfo);
731 BigInteger dpnId = interfaceInfo.getDpId();
732 long groupId = ElanUtils.getElanRemoteBCGID(elanInfo.getElanTag());
733 GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, listBucketInfo);
734 mdsalManager.syncInstallGroup(groupEntity, ElanConstants.DELAY_TIME_IN_MILLISECOND);
737 public void removeRemoteBroadcastGroup(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
738 List<BucketInfo> listBucketInfo = getRemoteBCGroupBucketInfos(elanInfo, interfaceInfo);
739 BigInteger dpnId = interfaceInfo.getDpId();
740 long groupId = ElanUtils.getElanRemoteBCGID(elanInfo.getElanTag());
741 GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, listBucketInfo);
742 logger.trace("deleting the remoteBroadCast GroupEntity:{}", groupEntity);
743 mdsalManager.syncRemoveGroup(groupEntity);
746 public void setupTerminateServiceTable(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
747 long elanTag = elanInfo.getElanTag();
748 //FIXME [ELANBE] Removing ITM API for now, will need this for multi dpn.
749 // FlowEntity flowEntity = MDSALUtil.buildFlowEntity(interfaceInfo.getDpId(), ITMConstants.TERMINATING_SERVICE_TABLE, getFlowRef(ITMConstants.TERMINATING_SERVICE_TABLE, elanTag),
750 // 5, elanInfo.getElanInstanceName(), 0, 0, ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(elanTag)), itmManager.getTunnelMatchesForServiceId(elanTag),
751 // getInstructionsForOutGroup(ElanUtils.getElanLocalBCGID(elanTag)));
753 // mdsalManager.installFlow(flowEntity);
756 public void setupUnknownDMacTable(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
757 long elanTag = elanInfo.getElanTag();
758 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(interfaceInfo.getDpId(), ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, getFlowRef(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, elanTag),
759 5, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_UNKNOWN_DMAC.add(BigInteger.valueOf(elanTag)), getMatchesForElanTag(elanTag),
760 getInstructionsForOutGroup(ElanUtils.getElanLocalBCGID(elanTag)));
762 mdsalManager.installFlow(flowEntity);
765 private void removeStaticELanFlows(final ElanInstance elanInfo, final InterfaceInfo interfaceInfo) {
766 BigInteger dpId = interfaceInfo.getDpId();
767 long elanTag = elanInfo.getElanTag();
769 * If there are not elan ports, remove the unknown smac and default dmac
772 DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanInfo.getElanInstanceName(), dpId);
773 if(dpnInterfaces == null) {
776 List <String> elanInterfaces = dpnInterfaces.getInterfaces();
777 if (elanInterfaces == null || elanInterfaces.isEmpty()) {
779 logger.debug("deleting the elan: {} present on dpId: {}", elanInfo.getElanInstanceName(), dpId);
780 removeDefaultTermFlow(dpId, elanInfo.getElanTag());
781 removeUnknownDmacFlow(dpId, elanInfo);
782 removeRemoteBroadcastGroup(elanInfo, interfaceInfo);
783 removeLocalBroadcastGroup(elanInfo, interfaceInfo);
785 setupLocalBroadcastGroups(elanInfo, interfaceInfo);
789 private void removeUnknownDmacFlow(BigInteger dpId, ElanInstance elanInfo) {
790 FlowEntity flowEntity = getUnknownDmacFlowEntity(dpId, elanInfo);
791 mdsalManager.syncRemoveFlow(flowEntity, ElanConstants.DELAY_TIME_IN_MILLISECOND);
794 private void removeDefaultTermFlow(BigInteger dpId, long elanTag) {
795 //FIXME [ELANBE] Removing ITM API for now, will need this for multi dpn.
796 //itmManager.removeTerminatingServiceAction(dpId, (int) elanTag);
799 private void bindService(ElanInstance elanInfo, String interfaceName) {
800 // interfaceManager.bindService(interfaceName, ElanUtils.getServiceInfo(elanInfo.getElanInstanceName(), elanInfo.getElanTag(), interfaceName));
802 int priority = ElanConstants.ELAN_SERVICE_PRIORITY;
803 int instructionKey = 0;
804 List<Instruction> instructions = new ArrayList<Instruction>();
805 instructions.add(MDSALUtil.buildAndGetWriteMetadaInstruction(ElanUtils.getElanMetadataLabel(elanInfo.getElanTag()), MetaDataUtil.METADATA_MASK_SERVICE, ++instructionKey));
806 instructions.add(MDSALUtil.buildAndGetGotoTableInstruction(ElanConstants.ELAN_SMAC_TABLE, ++instructionKey));
809 ElanUtils.getBoundServices(String.format("%s.%s.%s", "vpn",elanInfo.getElanInstanceName(), interfaceName),
810 ElanConstants.ELAN_SERVICE_INDEX, priority,
811 ElanConstants.COOKIE_ELAN_INGRESS_TABLE, instructions);
812 ElanUtils.syncWrite(broker, LogicalDatastoreType.CONFIGURATION,
813 ElanUtils.buildServiceId(interfaceName, ElanConstants.ELAN_SERVICE_INDEX), serviceInfo);
816 private void unbindService(ElanInstance elanInfo, String interfaceName) {
817 ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION,
818 ElanUtils.buildServiceId(interfaceName,ElanConstants.ELAN_SERVICE_INDEX),
819 ElanUtils.DEFAULT_CALLBACK);
822 private void unbindService(ElanInstance elanInfo, String interfaceName, int vlanId) {
823 ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION,
824 ElanUtils.buildServiceId(interfaceName,ElanConstants.ELAN_SERVICE_INDEX),
825 ElanUtils.DEFAULT_CALLBACK);
828 private FlowEntity getUnknownDmacFlowEntity(BigInteger dpId, ElanInstance elanInfo) {
829 long elanTag = elanInfo.getElanTag();
830 List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
832 mkMatches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
833 ElanUtils.getElanMetadataLabel(elanTag),
834 MetaDataUtil.METADATA_MASK_SERVICE }));
836 List<InstructionInfo> mkInstructions = new ArrayList<InstructionInfo>();
837 List <ActionInfo> actionsInfos = new ArrayList <ActionInfo> ();
838 actionsInfos.add(new ActionInfo(ActionType.group, new String[]{Long.toString(ElanUtils.getElanRemoteBCGID(elanTag))}));
839 mkInstructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos));
841 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, getFlowRef(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, elanTag),
842 5, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_UNKNOWN_DMAC.add(BigInteger.valueOf(elanTag)),
843 mkMatches, mkInstructions);
847 private String getFlowRef(long tableId, long elanTag) {
848 return new StringBuffer().append(tableId).append(elanTag).toString();
851 private List<ActionInfo> getInterfacePortActionInfos(InterfaceInfo interfaceInfo) {
852 List<ActionInfo> listActionInfo = new ArrayList<ActionInfo>();
853 listActionInfo.add(getReg1ActionInfo(interfaceInfo.getInterfaceTag()));
854 listActionInfo.add(new ActionInfo(ActionType.nx_resubmit, new String[]{}));
855 return listActionInfo;
858 private void updateElanDpnInterfacesList(String elanInstanceName, BigInteger dpId, List<String> interfaceNames) {
859 if(!interfaceNames.isEmpty()) {
860 DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId)
861 .setInterfaces(interfaceNames).setKey(new DpnInterfacesKey(dpId)).build();
862 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId),
865 MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId));
870 private List<String> createElanInterfacesList(String elanInstanceName, String interfaceName, BigInteger dpId) {
871 List<String> interfaceNames = new ArrayList<String>();
872 interfaceNames.add(interfaceName);
873 DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId)
874 .setInterfaces(interfaceNames).setKey(new DpnInterfacesKey(dpId)).build();
875 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId),
877 return interfaceNames;
880 private void createElanInterfaceTablesList(String interfaceName) {
881 InstanceIdentifier<ElanInterfaceMac> elanInterfaceMacTables = ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName);
882 Optional<ElanInterfaceMac> interfaceMacTables = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanInterfaceMacTables);
883 // Adding new Elan Interface Port to the operational DataStore without Static-Mac Entries..
884 if(!interfaceMacTables.isPresent()) {
885 ElanInterfaceMac elanInterfaceMacTable = new ElanInterfaceMacBuilder().setElanInterface(interfaceName).setKey(new ElanInterfaceMacKey(interfaceName)).build();
886 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName),
887 elanInterfaceMacTable);
891 private void createElanStateList(String elanInstanceName, String interfaceName) {
892 InstanceIdentifier<Elan> elanInstance = ElanUtils.getElanInstanceOperationalDataPath(elanInstanceName);
893 Optional<Elan> elanInterfaceLists = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanInstance);
894 // Adding new Elan Interface Port to the operational DataStore without Static-Mac Entries..
895 if(elanInterfaceLists.isPresent()) {
896 List<String> interfaceLists = elanInterfaceLists.get().getElanInterfaces();
897 if(interfaceLists == null) {
898 interfaceLists = new ArrayList<>();
900 interfaceLists.add(interfaceName);
901 Elan elanState = new ElanBuilder().setName(elanInstanceName).setElanInterfaces(interfaceLists).setKey(new ElanKey(elanInstanceName)).build();
902 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanInstanceName), elanState);
906 private boolean isOperational(InterfaceInfo interfaceInfo) {
907 return ((interfaceInfo.getOpState() == InterfaceInfo.InterfaceOpState.UP) && (interfaceInfo.getAdminState() == InterfaceInfo.InterfaceAdminState.ENABLED));
910 protected void updatedIfPrimaryAttributeChanged(ElanInterface elanInterface, boolean isUpdated) {
911 String interfaceName = elanInterface.getName();
912 InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
913 BigInteger dpId = interfaceInfo.getDpId();
914 InstanceIdentifier<ElanInterfaceMac> elanInterfaceId = ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName);
915 Optional<ElanInterfaceMac> existingElanInterface = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanInterfaceId);
916 ElanInstance elanInfo = ElanUtils.getElanInstanceByName(elanInterface.getElanInstanceName());
918 if(!existingElanInterface.isPresent()) {
922 List<MacEntry> macEntries = existingElanInterface.get().getMacEntry();
923 if(macEntries != null && !macEntries.isEmpty()) {
924 for (MacEntry macEntry : macEntries) {
926 ElanUtils.setupMacFlows(elanInfo, interfaceInfo, ElanConstants.STATIC_MAC_TIMEOUT, macEntry.getMacAddress().getValue());
928 ElanUtils.deleteMacFlows(elanInfo, interfaceInfo, macEntry);
933 InstanceIdentifier<DpnInterfaces> dpnInterfaceId = ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInterface.getElanInstanceName(), interfaceInfo.getDpId());
934 Optional<DpnInterfaces> dpnInterfaces = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, dpnInterfaceId);
935 List<String> interfaceLists = dpnInterfaces.get().getInterfaces();
938 interfaceLists.add(elanInterface.getName());
940 interfaceLists.remove(elanInterface.getName());
943 DpnInterfaces updateDpnInterfaces = new DpnInterfacesBuilder().setInterfaces(interfaceLists).setDpId(dpId).setKey(new DpnInterfacesKey(dpId)).build();
944 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, dpnInterfaceId, updateDpnInterfaces);
947 installFlowsAndGroups(elanInfo, interfaceInfo);
949 removeStaticELanFlows(elanInfo, interfaceInfo);
950 unbindService(elanInfo, interfaceName);
954 public void handleTunnelStateEvent(BigInteger srcDpId, BigInteger dstDpId) {
955 ElanDpnInterfaces dpnInterfaceLists = ElanUtils.getElanDpnInterfacesList();
956 Set<String> elanInstancesMap = new HashSet<>();
957 if(dpnInterfaceLists == null) {
960 List<ElanDpnInterfacesList> elanDpnIf = dpnInterfaceLists.getElanDpnInterfacesList();
961 for(ElanDpnInterfacesList elanDpns: elanDpnIf) {
963 String elanName = elanDpns.getElanInstanceName();
964 List<DpnInterfaces> dpnInterfaces = elanDpns.getDpnInterfaces();
965 if(dpnInterfaces == null) {
968 for (DpnInterfaces dpnIf : dpnInterfaces) {
969 if(dpnIf.getDpId().equals(srcDpId) || dpnIf.getDpId().equals(dstDpId)) {
974 logger.debug("Elan instance:{} is present b/w srcDpn:{} and dstDpn:{}", elanName, srcDpId, dstDpId);
975 DpnInterfaces dpnInterface = ElanUtils.getElanInterfaceInfoByElanDpn(elanName, srcDpId);
976 Set<String> interfaceLists = new HashSet<>();
977 ElanInstance elanInfo = ElanUtils.getElanInstanceByName(elanName);
978 interfaceLists.addAll(dpnInterface.getInterfaces());
979 for(String ifName : interfaceLists) {
980 InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(ifName);
981 if (isOperational(interfaceInfo)) {
982 if (interfaceInfo.getDpId().equals(srcDpId) && !elanInstancesMap.contains(elanDpns.getElanInstanceName())) {
983 elanInstancesMap.add(elanDpns.getElanInstanceName());
984 elanInterfaceManager.updateRemoteBCGrouponDpnTunnelEvent(elanInfo, interfaceInfo, dstDpId);
986 elanInterfaceManager.installDMacAddressTables(elanInfo, interfaceInfo, dstDpId);
994 public void handleInterfaceUpated(InterfaceInfo interfaceInfo, ElanInstance elanInstance, boolean isStateUp) {
995 BigInteger dpId = interfaceInfo.getDpId();
996 String elanName = elanInstance.getElanInstanceName();
997 String ifName = interfaceInfo.getInterfaceName();
998 logger.trace("Handling interface update event for interface with info {} , state {}", interfaceInfo, isStateUp);
1001 DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanName, dpId);
1002 if(dpnInterfaces == null) {
1003 createElanInterfacesList(elanName, interfaceInfo.getInterfaceName(), dpId);
1005 List<String> dpnElanInterfaces = dpnInterfaces.getInterfaces();
1006 dpnElanInterfaces.add(interfaceInfo.getInterfaceName());
1007 DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId)
1008 .setInterfaces(dpnElanInterfaces).setKey(new DpnInterfacesKey(dpId)).build();
1009 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanName, interfaceInfo.getDpId()), dpnInterface);
1012 logger.trace("ElanInterface Service is installed for interface:{}", ifName);
1013 elanInterfaceManager.installFlowsAndGroups(elanInstance, interfaceInfo);
1014 elanInterfaceManager.installMacAddressTables(elanInstance, interfaceInfo);
1017 DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanName, dpId);
1018 if(dpnInterfaces != null) {
1019 List<String> dpnElanInterfaces = dpnInterfaces.getInterfaces();
1020 dpnElanInterfaces.remove(interfaceInfo.getInterfaceName());
1021 DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId)
1022 .setInterfaces(dpnElanInterfaces).setKey(new DpnInterfacesKey(dpId)).build();
1023 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanName, interfaceInfo.getDpId()), dpnInterface);
1025 logger.trace("ElanInterface Service is removed for the interface:{}", ifName);
1026 elanInterfaceManager.removeMacAddressTables(elanInstance, interfaceInfo);
1027 elanInterfaceManager.removeFlowsAndGroups(elanInstance, interfaceInfo);
1031 private List<MatchInfo> getMatchesForFilterEqualsLPortTag(Long LportTag) {
1032 List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
1033 // Matching metadata
1034 mkMatches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
1035 ElanUtils.getElanMetadataLabel(LportTag),
1036 MetaDataUtil.METADATA_MASK_SERVICE }));
1037 mkMatches.add(new MatchInfo(MatchFieldType.reg1, new long[] {LportTag.longValue()}));
1042 private List<MatchInfo> getMatchesForFilterEqualsReg1LPortTag(Long LportTag) {
1043 List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
1044 // Matching metadata
1045 mkMatches.add(new MatchInfo(MatchFieldType.reg1, new long[] {
1046 (LportTag.longValue())}));
1052 public static class RegMatch {
1054 final Class<? extends NxmNxReg> reg;
1057 public RegMatch(Class<? extends NxmNxReg> reg, Long value) {
1063 public static RegMatch of(Class<? extends NxmNxReg> reg, Long value) {
1064 return new RegMatch(reg, value);
1068 public static void addNxRegMatch(MatchBuilder match, RegMatch... matches) {
1069 ArrayList<ExtensionList> extensions = new ArrayList<>();
1070 for (RegMatch rm : matches) {
1071 Class<? extends ExtensionKey> key;
1072 if (NxmNxReg0.class.equals(rm.reg)) {
1073 key = NxmNxReg0Key.class;
1074 } else if (NxmNxReg1.class.equals(rm.reg)) {
1075 key = NxmNxReg1Key.class;
1076 } else if (NxmNxReg2.class.equals(rm.reg)) {
1077 key = NxmNxReg2Key.class;
1078 } else if (NxmNxReg3.class.equals(rm.reg)) {
1079 key = NxmNxReg3Key.class;
1080 } else if (NxmNxReg4.class.equals(rm.reg)) {
1081 key = NxmNxReg4Key.class;
1082 } else if (NxmNxReg5.class.equals(rm.reg)) {
1083 key = NxmNxReg5Key.class;
1084 } else if (NxmNxReg6.class.equals(rm.reg)) {
1085 key = NxmNxReg6Key.class;
1087 key = NxmNxReg7Key.class;
1089 NxAugMatchNodesNodeTableFlow am = new NxAugMatchNodesNodeTableFlowBuilder().setNxmNxReg(
1090 new NxmNxRegBuilder().setReg(rm.reg).setValue(rm.value).build()).build();
1091 extensions.add(new ExtensionListBuilder().setExtensionKey(key)
1092 .setExtension(new ExtensionBuilder().addAugmentation(NxAugMatchNodesNodeTableFlow.class, am).build())
1095 GeneralAugMatchNodesNodeTableFlow m = new GeneralAugMatchNodesNodeTableFlowBuilder().setExtensionList(
1096 extensions).build();
1097 match.addAugmentation(GeneralAugMatchNodesNodeTableFlow.class, m);
1102 private List<InstructionInfo> getInstructionsInPortForOutGroup(
1104 List<InstructionInfo> mkInstructions = new ArrayList<InstructionInfo>();
1105 List <ActionInfo> actionsInfos = new ArrayList <ActionInfo> ();
1106 actionsInfos.add(new ActionInfo(ActionType.nx_resubmit, new String[]{ "123"}));
1107 actionsInfos.add(new ActionInfo(ActionType.group, new String[]{Long.toString(GroupId)}));
1108 mkInstructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos));
1109 return mkInstructions;
1112 private List<InstructionInfo> getInstructionsInPortForOutGroup(
1114 List<InstructionInfo> mkInstructions = new ArrayList<InstructionInfo>();
1115 List <ActionInfo> actionsInfos = new ArrayList <ActionInfo> ();
1116 //TODO: modify in-port action
1117 //actionsInfos.add(new ActionInfo(ActionType.set_source_port_field, new String[]{ "255"}));
1118 actionsInfos.addAll(getEgressActionsForInterface(ifName));
1119 mkInstructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos));
1120 return mkInstructions;
1125 private List<InstructionInfo> getInstructionsDrop() {
1126 List<InstructionInfo> mkInstructions = new ArrayList<InstructionInfo>();
1127 List <ActionInfo> actionsInfos = new ArrayList <ActionInfo> ();
1128 actionsInfos.add(new ActionInfo(ActionType.drop_action, new String[]{}));
1129 mkInstructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos));
1130 return mkInstructions;