2 * Copyright (c) 2016, 2018 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.genius.interfacemanager;
10 import static org.opendaylight.mdsal.binding.util.Datastore.CONFIGURATION;
12 import com.google.common.util.concurrent.ListenableFuture;
13 import java.util.ArrayList;
14 import java.util.Collections;
15 import java.util.List;
17 import java.util.concurrent.Callable;
18 import java.util.concurrent.ConcurrentHashMap;
19 import java.util.concurrent.ExecutionException;
20 import java.util.concurrent.Future;
21 import javax.annotation.PreDestroy;
22 import javax.inject.Inject;
23 import javax.inject.Singleton;
24 import org.apache.aries.blueprint.annotation.service.Reference;
25 import org.eclipse.jdt.annotation.Nullable;
26 import org.opendaylight.genius.datastoreutils.ExpectedDataObjectNotFoundException;
27 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
28 import org.opendaylight.genius.interfacemanager.commons.InterfaceManagerCommonUtils;
29 import org.opendaylight.genius.interfacemanager.commons.InterfaceMetaUtils;
30 import org.opendaylight.genius.interfacemanager.diagstatus.IfmDiagStatusProvider;
31 import org.opendaylight.genius.interfacemanager.exceptions.InterfaceAlreadyExistsException;
32 import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo;
33 import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo.InterfaceAdminState;
34 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
35 import org.opendaylight.genius.interfacemanager.listeners.InternalTunnelCache;
36 import org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.SouthboundUtils;
37 import org.opendaylight.genius.interfacemanager.rpcservice.InterfaceManagerRpcService;
38 import org.opendaylight.genius.interfacemanager.servicebindings.flowbased.utilities.FlowBasedServicesUtils;
39 import org.opendaylight.genius.mdsalutil.ActionInfo;
40 import org.opendaylight.infrautils.diagstatus.ServiceState;
41 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
42 import org.opendaylight.infrautils.utils.concurrent.LoggingFutures;
43 import org.opendaylight.mdsal.binding.api.DataBroker;
44 import org.opendaylight.mdsal.binding.api.ReadTransaction;
45 import org.opendaylight.mdsal.binding.util.Datastore.Configuration;
46 import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunner;
47 import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunnerImpl;
48 import org.opendaylight.mdsal.binding.util.TypedWriteTransaction;
49 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
50 import org.opendaylight.mdsal.eos.binding.api.Entity;
51 import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipCandidateRegistration;
52 import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipService;
53 import org.opendaylight.mdsal.eos.common.api.CandidateAlreadyRegisteredException;
54 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev170119.L2vlan;
55 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev170119.Tunnel;
56 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
57 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
58 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
59 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
60 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus;
61 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus;
62 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInput;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInputBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolOutput;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.config.rev160406.IfmConfig;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info.InterfaceParentEntry;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info._interface.parent.entry.InterfaceChildEntry;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info._interface.parent.entry.InterfaceChildEntryKey;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge.ref.info.BridgeRefEntry;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfExternal;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfExternalBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlanBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefs;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefsBuilder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEndpointIpForDpnInput;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEndpointIpForDpnInputBuilder;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEndpointIpForDpnOutput;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceInput;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceInputBuilder;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceOutput;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeBase;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeEgress;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeIngress;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServices;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeBase;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
96 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
97 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
98 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
99 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
100 import org.opendaylight.yangtools.yang.common.RpcResult;
101 import org.opendaylight.yangtools.yang.common.Uint64;
102 import org.slf4j.Logger;
103 import org.slf4j.LoggerFactory;
106 public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
107 private static final Logger LOG = LoggerFactory.getLogger(InterfacemgrProvider.class);
109 private final DataBroker dataBroker;
110 private final ManagedNewTransactionRunner txRunner;
111 private final IdManagerService idManager;
112 private final InterfaceManagerRpcService interfaceManagerRpcService;
113 private final EntityOwnershipService entityOwnershipService;
114 private final JobCoordinator coordinator;
115 private final InterfaceManagerCommonUtils interfaceManagerCommonUtils;
116 private final InterfaceMetaUtils interfaceMetaUtils;
117 private final IfmConfig ifmConfig;
118 private final IfmDiagStatusProvider ifmStatusProvider;
119 private Map<String, OvsdbTerminationPointAugmentation> ifaceToTpMap;
120 private Map<String, InstanceIdentifier<Node>> ifaceToNodeIidMap;
121 private Map<InstanceIdentifier<Node>, OvsdbBridgeAugmentation> nodeIidToBridgeMap;
122 private EntityOwnershipCandidateRegistration configEntityCandidate;
123 private EntityOwnershipCandidateRegistration bindingEntityCandidate;
124 private final InternalTunnelCache internalTunnelCache;
127 public InterfacemgrProvider(@Reference final DataBroker dataBroker,
128 final EntityOwnershipService entityOwnershipService,
129 final IdManagerService idManager,
130 final InterfaceManagerRpcService interfaceManagerRpcService,
131 @Reference final JobCoordinator coordinator,
132 final InterfaceManagerCommonUtils interfaceManagerCommonUtils,
133 final InterfaceMetaUtils interfaceMetaUtils,
134 final IfmConfig ifmConfig,
135 final IfmDiagStatusProvider ifmStatusProvider,
136 final InternalTunnelCache internalTunnelCache) {
137 this.dataBroker = dataBroker;
138 this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
139 this.entityOwnershipService = entityOwnershipService;
140 this.idManager = idManager;
141 this.interfaceManagerRpcService = interfaceManagerRpcService;
142 this.coordinator = coordinator;
143 this.interfaceManagerCommonUtils = interfaceManagerCommonUtils;
144 this.interfaceMetaUtils = interfaceMetaUtils;
145 this.ifmConfig = ifmConfig;
146 this.ifmStatusProvider = ifmStatusProvider;
147 this.internalTunnelCache = internalTunnelCache;
151 @SuppressWarnings("checkstyle:IllegalCatch")
152 public void start() {
155 configEntityCandidate = entityOwnershipService.registerCandidate(
156 new Entity(IfmConstants.INTERFACE_CONFIG_ENTITY, IfmConstants.INTERFACE_CONFIG_ENTITY));
157 bindingEntityCandidate = entityOwnershipService.registerCandidate(
158 new Entity(IfmConstants.INTERFACE_SERVICE_BINDING_ENTITY,
159 IfmConstants.INTERFACE_SERVICE_BINDING_ENTITY));
160 this.ifaceToTpMap = new ConcurrentHashMap<>();
161 this.ifaceToNodeIidMap = new ConcurrentHashMap<>();
162 this.nodeIidToBridgeMap = new ConcurrentHashMap<>();
163 ifmStatusProvider.reportStatus(ServiceState.OPERATIONAL);
164 LOG.info("InterfacemgrProvider Started");
165 } catch (CandidateAlreadyRegisteredException e) {
166 LOG.error("Failed to register entity {} with EntityOwnershipService", e.getEntity());
167 ifmStatusProvider.reportStatus(e);
168 } catch (InterruptedException | ExecutionException e) {
169 LOG.error("Failed to create idPool for InterfaceMgr", e);
175 public void close() throws Exception {
176 if (configEntityCandidate != null) {
177 configEntityCandidate.close();
180 if (bindingEntityCandidate != null) {
181 bindingEntityCandidate.close();
183 ifmStatusProvider.reportStatus(ServiceState.UNREGISTERED);
184 LOG.info("InterfacemgrProvider Closed");
187 public EntityOwnershipService getEntityOwnershipService() {
188 return entityOwnershipService;
191 public DataBroker getDataBroker() {
192 return this.dataBroker;
195 private void createIdPool() throws ExecutionException, InterruptedException {
196 CreateIdPoolInput createPool = new CreateIdPoolInputBuilder().setPoolName(IfmConstants.IFM_IDPOOL_NAME)
197 .setLow(IfmConstants.IFM_ID_POOL_START).setHigh(IfmConstants.IFM_ID_POOL_END).build();
198 // TODO: Error handling
199 ListenableFuture<RpcResult<CreateIdPoolOutput>> result = idManager.createIdPool(createPool);
200 if (result != null && result.get().isSuccessful()) {
201 LOG.debug("Created IdPool for InterfaceMgr");
206 public Long getPortForInterface(String ifName) {
207 GetPortFromInterfaceInput input = new GetPortFromInterfaceInputBuilder().setIntfName(ifName).build();
208 Future<RpcResult<GetPortFromInterfaceOutput>> output = interfaceManagerRpcService.getPortFromInterface(input);
210 RpcResult<GetPortFromInterfaceOutput> port = output.get();
211 if (port.isSuccessful()) {
212 return port.getResult().getPortno().toJava();
214 } catch (NullPointerException | InterruptedException | ExecutionException e) {
215 LOG.warn("Exception when getting port for interface", e);
221 public Long getPortForInterface(Interface intf) {
222 GetPortFromInterfaceInput input = new GetPortFromInterfaceInputBuilder().setIntfName(intf.getName()).build();
223 Future<RpcResult<GetPortFromInterfaceOutput>> output = interfaceManagerRpcService.getPortFromInterface(input);
225 RpcResult<GetPortFromInterfaceOutput> port = output.get();
226 if (port.isSuccessful()) {
227 return port.getResult().getPortno().toJava();
229 } catch (NullPointerException | InterruptedException | ExecutionException e) {
230 LOG.warn("Exception when getting port for interface", e);
236 public InterfaceInfo getInterfaceInfo(String interfaceName) {
238 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
239 .ietf.interfaces.rev140508.interfaces.state.Interface ifState = interfaceManagerCommonUtils
240 .getInterfaceState(interfaceName);
242 if (ifState == null) {
243 LOG.debug("Interface {} is not present", interfaceName);
247 Interface intf = interfaceManagerCommonUtils.getInterfaceFromConfigDS(new InterfaceKey(interfaceName));
249 LOG.warn("Interface {} doesn't exist in config datastore", interfaceName);
253 NodeConnectorId ncId = FlowBasedServicesUtils.getNodeConnectorIdFromInterface(intf.getName(),
254 interfaceManagerCommonUtils);
255 InterfaceInfo.InterfaceType interfaceType = IfmUtil.getInterfaceType(intf);
256 InterfaceInfo interfaceInfo = new InterfaceInfo(interfaceName);
257 Integer portNo = org.opendaylight.genius.interfacemanager.globals.IfmConstants.INVALID_PORT_NO;
260 dpId = IfmUtil.getDpnFromNodeConnectorId(ncId);
261 portNo = Integer.parseInt(IfmUtil.getPortNoFromNodeConnectorId(ncId));
265 if (interfaceType == InterfaceInfo.InterfaceType.VLAN_INTERFACE) {
266 interfaceInfo = IfmUtil.getVlanInterfaceInfo(intf, dpId);
267 } else if (interfaceType == InterfaceInfo.InterfaceType.UNKNOWN_INTERFACE) {
268 LOG.error("Type of Interface {} is unknown", interfaceName);
271 interfaceInfo.setDpId(dpId);
272 interfaceInfo.setPortNo(portNo);
273 interfaceInfo.setAdminState(intf.isEnabled() ? InterfaceAdminState.ENABLED : InterfaceAdminState.DISABLED);
274 interfaceInfo.setInterfaceName(interfaceName);
275 Integer lportTag = ifState.getIfIndex();
276 interfaceInfo.setInterfaceTag(lportTag);
277 interfaceInfo.setInterfaceType(interfaceType);
278 interfaceInfo.setGroupId(IfmUtil.getGroupId(lportTag, interfaceType));
279 interfaceInfo.setOpState(InterfaceInfo.InterfaceOpState.fromModel(ifState.getOperStatus()));
280 PhysAddress phyAddress = ifState.getPhysAddress();
281 if (phyAddress != null) {
282 interfaceInfo.setMacAddress(ifState.getPhysAddress().getValue());
285 return interfaceInfo;
290 public InterfaceInfo getInterfaceInfoFromOperationalDataStore(String interfaceName,
291 InterfaceInfo.InterfaceType interfaceType) {
292 InterfaceInfo interfaceInfo = new InterfaceInfo(interfaceName);
293 org.opendaylight.yang.gen.v1.urn
294 .ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState =
295 interfaceManagerCommonUtils.getInterfaceState(interfaceName);
296 if (ifState == null) {
297 LOG.debug("Interface {} is not present", interfaceName);
300 NodeConnectorId ncId = IfmUtil.getNodeConnectorIdFromInterface(ifState);
302 interfaceInfo.setDpId(IfmUtil.getDpnFromNodeConnectorId(ncId));
303 interfaceInfo.setPortNo(Integer.parseInt(IfmUtil.getPortNoFromNodeConnectorId(ncId)));
305 interfaceInfo.setAdminState(ifState.getAdminStatus() == AdminStatus.Up ? InterfaceAdminState.ENABLED
306 : InterfaceAdminState.DISABLED);
307 interfaceInfo.setInterfaceName(interfaceName);
308 Integer lportTag = ifState.getIfIndex();
309 interfaceInfo.setInterfaceTag(lportTag);
310 interfaceInfo.setInterfaceType(interfaceType);
311 interfaceInfo.setGroupId(IfmUtil.getGroupId(lportTag, interfaceType));
312 interfaceInfo.setOpState(InterfaceInfo.InterfaceOpState.fromModel(ifState.getOperStatus()));
313 PhysAddress phyAddress = ifState.getPhysAddress();
314 if (phyAddress != null) {
315 interfaceInfo.setMacAddress(ifState.getPhysAddress().getValue());
317 return interfaceInfo;
321 public InterfaceInfo getInterfaceInfoFromOperationalDataStore(String interfaceName) {
322 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
323 .ietf.interfaces.rev140508.interfaces.state.Interface ifState = interfaceManagerCommonUtils
324 .getInterfaceState(interfaceName);
325 if (ifState == null) {
326 LOG.debug("Interface {} is not present", interfaceName);
330 return populateInterfaceInfo(interfaceName, ifState);
333 public InterfaceInfo populateInterfaceInfo(String interfaceName,
334 org.opendaylight.yang.gen.v1.urn
335 .ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState) {
336 InterfaceInfo interfaceInfo = new InterfaceInfo(interfaceName);
337 NodeConnectorId ncId = IfmUtil.getNodeConnectorIdFromInterface(ifState);
339 if (Tunnel.class.equals(ifState.getType())) {
340 interfaceInfo.setPortName(interfaceName);
342 Interface iface = interfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceName);
344 ParentRefs parentRefs = iface.augmentation(ParentRefs.class);
345 interfaceInfo.setPortName(parentRefs.getParentInterface());
348 interfaceInfo.setDpId(IfmUtil.getDpnFromNodeConnectorId(ncId));
349 interfaceInfo.setPortNo(Integer.parseInt(IfmUtil.getPortNoFromNodeConnectorId(ncId)));
351 interfaceInfo.setAdminState(ifState.getAdminStatus() == AdminStatus.Up ? InterfaceAdminState.ENABLED
352 : InterfaceAdminState.DISABLED);
353 interfaceInfo.setInterfaceName(interfaceName);
354 Integer lportTag = ifState.getIfIndex();
355 if (lportTag != null) {
356 interfaceInfo.setInterfaceTag(lportTag);
358 interfaceInfo.setOpState(InterfaceInfo.InterfaceOpState.fromModel(ifState.getOperStatus()));
359 PhysAddress phyAddress = ifState.getPhysAddress();
360 if (phyAddress != null) {
361 interfaceInfo.setMacAddress(ifState.getPhysAddress().getValue());
363 return interfaceInfo;
367 public InterfaceInfo getInterfaceInfoFromOperationalDSCache(String interfaceName) {
368 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
369 .ietf.interfaces.rev140508.interfaces.state.Interface ifState = interfaceManagerCommonUtils
370 .getInterfaceStateFromCache(interfaceName);
371 if (ifState == null) {
372 LOG.warn("Interface {} is not present", interfaceName);
375 return populateInterfaceInfo(interfaceName, ifState);
379 public Interface getInterfaceInfoFromConfigDataStore(String interfaceName) {
380 return interfaceManagerCommonUtils.getInterfaceFromConfigDS(new InterfaceKey(interfaceName));
384 public Interface getInterfaceInfoFromConfigDataStore(ReadTransaction tx, String interfaceName)
385 throws ExecutionException, InterruptedException {
386 return interfaceManagerCommonUtils.getInterfaceFromConfigDS(tx, new InterfaceKey(interfaceName));
390 public void createVLANInterface(String interfaceName, String portName, Uint64 dpId, Integer vlanId,
391 String description, IfL2vlan.L2vlanMode l2vlanMode) throws InterfaceAlreadyExistsException {
392 createVLANInterface(interfaceName, portName, vlanId, description, l2vlanMode);
396 public ListenableFuture<?> createVLANInterface(String interfaceName, String portName, Integer vlanId,
397 String description, IfL2vlan.L2vlanMode l2vlanMode) throws InterfaceAlreadyExistsException {
398 return createVLANInterface(interfaceName, portName, vlanId, description, l2vlanMode, false);
402 public void createVLANInterface(String interfaceName, String portName, Uint64 dpId, Integer vlanId,
403 String description, IfL2vlan.L2vlanMode l2vlanMode, boolean isExternal)
404 throws InterfaceAlreadyExistsException {
405 createVLANInterface(interfaceName, portName, vlanId, description, l2vlanMode, isExternal);
409 public ListenableFuture<?> createVLANInterface(String interfaceName, String portName, Integer vlanId,
410 String description, IfL2vlan.L2vlanMode l2vlanMode,
412 throws InterfaceAlreadyExistsException {
414 LOG.info("Create VLAN interface : {}", interfaceName);
415 Interface interfaceOptional = interfaceManagerCommonUtils
416 .getInterfaceFromConfigDS(new InterfaceKey(interfaceName));
417 if (interfaceOptional != null) {
418 LOG.debug("VLAN interface already exists {} ", interfaceOptional.getDescription());
419 throw new InterfaceAlreadyExistsException(interfaceOptional.getName());
421 IfL2vlanBuilder l2vlanBuilder = new IfL2vlanBuilder().setL2vlanMode(l2vlanMode);
422 if (vlanId != null && vlanId > 0) {
423 l2vlanBuilder.setVlanId(new VlanId(vlanId));
425 InterfaceBuilder interfaceBuilder = new InterfaceBuilder().setEnabled(true).setName(interfaceName)
426 .setType(L2vlan.class).addAugmentation(l2vlanBuilder.build())
427 .addAugmentation(new ParentRefsBuilder().setParentInterface(portName).build())
428 .setDescription(description);
430 interfaceBuilder.addAugmentation(new IfExternalBuilder().setExternal(true).build());
432 InstanceIdentifier<Interface> interfaceIId = InterfaceManagerCommonUtils
433 .getInterfaceIdentifier(new InterfaceKey(interfaceName));
434 return LoggingFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
435 tx -> tx.mergeParentStructurePut(interfaceIId, interfaceBuilder.build())),
436 LOG, "Failed to (async) write {}", interfaceIId);
439 private boolean isServiceBoundOnInterface(short servicePriority, String interfaceName,
440 Class<? extends ServiceModeBase> serviceMode) {
441 InstanceIdentifier<BoundServices> boundServicesIId = IfmUtil.buildBoundServicesIId(servicePriority,
442 interfaceName, serviceMode);
444 return SingleTransactionDataBroker
445 .syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION, boundServicesIId).isPresent();
446 } catch (ExecutionException | InterruptedException e) {
447 LOG.warn("Error while reading [{}]", boundServicesIId, e);
453 public boolean isServiceBoundOnInterfaceForIngress(short servicePriority, String interfaceName) {
454 return isServiceBoundOnInterface(servicePriority, interfaceName, ServiceModeIngress.class);
458 public boolean isServiceBoundOnInterfaceForEgress(short servicePriority, String interfaceName) {
459 return isServiceBoundOnInterface(servicePriority, interfaceName, ServiceModeEgress.class);
463 public void bindService(String interfaceName, Class<? extends ServiceModeBase> serviceMode,
464 BoundServices serviceInfo) {
465 bindService(interfaceName, serviceMode, serviceInfo, /* WriteTransaction */ null);
469 public void bindService(String interfaceName, Class<? extends ServiceModeBase> serviceMode,
470 BoundServices serviceInfo, TypedWriteTransaction<Configuration> tx) {
472 LoggingFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
473 wtx -> IfmUtil.bindService(wtx, interfaceName, serviceInfo, serviceMode)), LOG,
474 "Error binding the InterfacemgrProvider service");
476 IfmUtil.bindService(tx, interfaceName, serviceInfo, serviceMode);
481 public void unbindService(String interfaceName, Class<? extends ServiceModeBase> serviceMode,
482 BoundServices serviceInfo) {
483 IfmUtil.unbindService(txRunner, coordinator, interfaceName,
484 FlowBasedServicesUtils.buildServiceId(interfaceName,
485 serviceInfo.getServicePriority().toJava(), serviceMode));
489 public Uint64 getDpnForInterface(Interface intrf) {
490 return getDpnForInterface(intrf.getName());
494 public Uint64 getDpnForInterface(String ifName) {
495 GetDpidFromInterfaceInput input = new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
496 Future<RpcResult<GetDpidFromInterfaceOutput>> output = interfaceManagerRpcService.getDpidFromInterface(input);
498 RpcResult<GetDpidFromInterfaceOutput> dpn = output.get();
499 if (dpn.isSuccessful()) {
500 return dpn.getResult().getDpid();
502 } catch (NullPointerException | InterruptedException | ExecutionException e) {
503 LOG.warn("Exception when getting port for interface", e);
509 public String getEndpointIpForDpn(Uint64 dpnId) {
510 GetEndpointIpForDpnInput input = new GetEndpointIpForDpnInputBuilder().setDpid(dpnId).build();
511 Future<RpcResult<GetEndpointIpForDpnOutput>> output = interfaceManagerRpcService.getEndpointIpForDpn(input);
513 RpcResult<GetEndpointIpForDpnOutput> ipForDpnOutputRpcResult = output.get();
514 if (ipForDpnOutputRpcResult.isSuccessful()) {
515 List<IpAddress> localIps = ipForDpnOutputRpcResult.getResult().getLocalIps();
516 if (localIps != null && !localIps.isEmpty()) {
517 return localIps.get(0).getIpv4Address().getValue();
520 } catch (NullPointerException | InterruptedException | ExecutionException e) {
521 LOG.warn("Exception when getting port for interface", e);
527 public List<ActionInfo> getInterfaceEgressActions(String ifName) {
528 return IfmUtil.getEgressActionInfosForInterface(ifName, 0, interfaceManagerCommonUtils, false);
532 public List<Interface> getVlanInterfaces() {
533 return interfaceManagerCommonUtils.getAllVlanInterfacesFromCache();
537 public List<Interface> getVxlanInterfaces() {
538 return interfaceManagerCommonUtils.getAllTunnelInterfacesFromCache();
542 public List<Interface> getChildInterfaces(String parentInterface) {
543 try (ReadTransaction tx = dataBroker.newReadOnlyTransaction()) {
544 return getChildInterfaces(tx, parentInterface);
545 } catch (ExecutionException | InterruptedException e) {
546 LOG.error("Error retrieving child interfaces of {} from config", parentInterface, e);
547 throw new RuntimeException("Error retrieving child interfaces of " + parentInterface + " from config", e);
552 public List<Interface> getChildInterfaces(ReadTransaction tx, String parentInterface) throws
553 ExecutionException, InterruptedException {
554 InterfaceParentEntry parentEntry = interfaceMetaUtils.getInterfaceParentEntryFromConfigDS(tx, parentInterface);
555 if (parentEntry == null) {
556 LOG.debug("No parent entry found for {}", parentInterface);
557 return Collections.emptyList();
560 @Nullable Map<InterfaceChildEntryKey, InterfaceChildEntry> childEntries = parentEntry.getInterfaceChildEntry();
561 if (childEntries == null || childEntries.isEmpty()) {
562 LOG.debug("No child entries found for parent {}", parentInterface);
563 return Collections.emptyList();
566 List<Interface> childInterfaces = new ArrayList<>();
567 for (InterfaceChildEntry childEntry : childEntries.values()) {
568 String interfaceName = childEntry.getChildInterface();
569 Interface iface = interfaceManagerCommonUtils.getInterfaceFromConfigDS(tx, interfaceName);
571 childInterfaces.add(iface);
573 LOG.debug("Child interface {} not found in config DS for parent interface {}", interfaceName,
578 LOG.trace("Found child interfaces {} for parent {}", childInterfaces, parentInterface);
579 return childInterfaces;
583 public boolean isExternalInterface(String interfaceName) {
584 return isExternalInterface(getInterfaceInfoFromConfigDataStore(interfaceName));
588 public boolean isExternalInterface(ReadTransaction tx, String interfaceName) throws
589 ExecutionException, InterruptedException {
590 return isExternalInterface(getInterfaceInfoFromConfigDataStore(tx, interfaceName));
593 private boolean isExternalInterface(Interface iface) {
598 IfExternal ifExternal = iface.augmentation(IfExternal.class);
599 return ifExternal != null && Boolean.TRUE.equals(ifExternal.isExternal());
603 public String getPortNameForInterface(NodeConnectorId nodeConnectorId, String interfaceName) {
604 return InterfaceManagerCommonUtils.getPortNameForInterface(nodeConnectorId, interfaceName);
608 public String getPortNameForInterface(String dpnId, String interfaceName) {
609 return InterfaceManagerCommonUtils.getPortNameForInterface(dpnId, interfaceName);
613 public Map<String, OvsdbTerminationPointAugmentation> getTerminationPointCache() {
614 return new ConcurrentHashMap<>(this.ifaceToTpMap);
618 public Map<String, OperStatus> getBfdStateCache() {
619 return interfaceManagerCommonUtils.getBfdStateMap();
622 public void addTerminationPointForInterface(String interfaceName,
623 OvsdbTerminationPointAugmentation terminationPoint) {
624 if (interfaceName != null && terminationPoint != null) {
625 LOG.debug("Adding TerminationPoint {} to cache for Interface {}", terminationPoint.getName(),
627 ifaceToTpMap.put(interfaceName, terminationPoint);
631 public OvsdbTerminationPointAugmentation getTerminationPoint(String interfaceName) {
632 return ifaceToTpMap.get(interfaceName);
635 public void removeTerminationPointForInterface(String interfaceName) {
636 LOG.debug("Removing TerminationPoint from cache for Interface {}", interfaceName);
637 if (interfaceName != null) {
638 ifaceToTpMap.remove(interfaceName);
642 public void addNodeIidForInterface(String interfaceName, InstanceIdentifier<Node> nodeIid) {
643 if (interfaceName != null && nodeIid != null) {
644 ifaceToNodeIidMap.put(interfaceName, nodeIid);
648 public void removeNodeIidForInterface(String interfaceName) {
649 if (interfaceName != null) {
650 ifaceToNodeIidMap.remove(interfaceName);
654 public InstanceIdentifier<Node> getNodeIidForInterface(String interfaceName) {
655 if (interfaceName != null) {
656 return ifaceToNodeIidMap.get(interfaceName);
661 private OvsdbBridgeAugmentation getBridgeForInterface(String interfaceName,
662 InstanceIdentifier<Node> nodeInstanceId) {
663 InstanceIdentifier<Node> nodeIid = nodeInstanceId;
664 if (nodeIid == null) {
665 nodeIid = getNodeIidForInterface(interfaceName);
667 return getBridgeForNodeIid(nodeIid);
670 public String getDpidForInterface(String interfaceName) {
671 return getDpidForInterface(interfaceName, null);
674 public String getDpidForInterface(String interfaceName, InstanceIdentifier<Node> nodeInstanceId) {
675 OvsdbBridgeAugmentation bridge = getBridgeForInterface(interfaceName, nodeInstanceId);
676 if (bridge != null) {
677 Uint64 dpid = IfmUtil.getDpnId(bridge.getDatapathId());
678 if (dpid != null && dpid.longValue() != 0) {
679 return String.valueOf(dpid);
685 public void addBridgeForNodeIid(InstanceIdentifier<Node> nodeIid, OvsdbBridgeAugmentation bridge) {
686 if (nodeIid != null && bridge != null) {
687 nodeIidToBridgeMap.put(nodeIid, bridge);
691 public void removeBridgeForNodeIid(InstanceIdentifier<Node> nodeIid) {
692 if (nodeIid != null) {
693 nodeIidToBridgeMap.remove(nodeIid);
697 public OvsdbBridgeAugmentation getBridgeForNodeIid(InstanceIdentifier<Node> nodeIid) {
698 if (nodeIid == null) {
702 OvsdbBridgeAugmentation ret = nodeIidToBridgeMap.get(nodeIid);
707 LOG.info("Node {} not found in cache, reading from md-sal", nodeIid);
710 node = SingleTransactionDataBroker.syncRead(
711 dataBroker, LogicalDatastoreType.OPERATIONAL, nodeIid);
712 } catch (ExpectedDataObjectNotFoundException e) {
713 LOG.error("Failed to read Node for {} ", nodeIid, e);
717 OvsdbBridgeAugmentation bridge = node.augmentation(OvsdbBridgeAugmentation.class);
718 if (bridge == null) {
719 LOG.error("Node {} has no bridge augmentation", nodeIid);
723 addBridgeForNodeIid(nodeIid, bridge);
728 public String getParentRefNameForInterface(String interfaceName) {
729 String parentRefName = null;
731 String dpnId = getDpidForInterface(interfaceName, null);
732 OvsdbTerminationPointAugmentation ovsdbTp = getTerminationPoint(interfaceName);
733 if (ovsdbTp != null) {
735 LOG.error("Got NULL dpnId when looking for TP with external ID {}", interfaceName);
738 parentRefName = getPortNameForInterface(dpnId, ovsdbTp.getName());
739 LOG.debug("Building parent ref for interface {}, using parentRefName {} acquired by external ID",
740 interfaceName, parentRefName);
742 LOG.debug("Skipping parent ref for interface {}, as there is no termination point that references "
743 + "this interface yet.", interfaceName);
746 return parentRefName;
750 public void updateInterfaceParentRef(String interfaceName, String parentInterface) {
751 // This should generally be called by EOS Owner for
752 // INTERFACE_CONFIG_ENTITY - runOnlyInLeaderNode()
753 updateInterfaceParentRef(interfaceName, parentInterface, true);
757 public void updateInterfaceParentRef(String interfaceName, String parentInterface,
758 boolean readInterfaceBeforeWrite) {
759 // This should generally be called by EOS Owner for
760 // INTERFACE_CONFIG_ENTITY - runOnlyInLeaderNode()
761 if (interfaceName == null) {
765 ParentRefUpdateWorker parentRefUpdateWorker = new ParentRefUpdateWorker(interfaceName, parentInterface,
766 readInterfaceBeforeWrite);
767 coordinator.enqueueJob(interfaceName, parentRefUpdateWorker, IfmConstants.JOB_MAX_RETRIES);
770 public class ParentRefUpdateWorker implements Callable<List<? extends ListenableFuture<?>>> {
771 String interfaceName;
772 String parentInterfaceName;
773 Boolean readInterfaceBeforeWrite;
775 public ParentRefUpdateWorker(String interfaceName, String parentInterfaceName,
776 boolean readInterfaceBeforeWrite) {
777 this.interfaceName = interfaceName;
778 this.parentInterfaceName = parentInterfaceName;
779 this.readInterfaceBeforeWrite = readInterfaceBeforeWrite;
783 public List<? extends ListenableFuture<?>> call() {
784 if (readInterfaceBeforeWrite) {
785 Interface iface = interfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceName);
787 LOG.debug("Interface doesn't exist in config DS - no need to update parentRef, skipping");
791 return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
792 tx -> IfmUtil.updateInterfaceParentRef(tx, interfaceName, parentInterfaceName)));
797 public OvsdbTerminationPointAugmentation getTerminationPointForInterface(String interfaceName) {
798 return getTerminationPoint(interfaceName);
802 public OvsdbBridgeAugmentation getOvsdbBridgeForInterface(String interfaceName) {
803 return getBridgeForInterface(interfaceName, null);
807 public OvsdbBridgeAugmentation getOvsdbBridgeForNodeIid(InstanceIdentifier<Node> nodeIid) {
808 return getBridgeForNodeIid(nodeIid);
813 * Get all termination points on a given DPN.
814 * This API uses read on Operational DS. If there are perf issues in cluster
815 * setup, we can consider caching later.
818 * Datapath Node Identifier
820 * @return If the data at the supplied path exists, returns a list of all termination point
823 public List<OvsdbTerminationPointAugmentation> getPortsOnBridge(Uint64 dpnId) {
824 List<OvsdbTerminationPointAugmentation> ports = new ArrayList<>();
825 Map<TerminationPointKey, TerminationPoint> portList = interfaceMetaUtils.getTerminationPointsOnBridge(dpnId);
826 for (TerminationPoint ovsPort : portList.values()) {
827 if (ovsPort.augmentation(OvsdbTerminationPointAugmentation.class) != null) {
828 ports.add(ovsPort.augmentation(OvsdbTerminationPointAugmentation.class));
831 LOG.debug("Found {} ports on bridge {}", ports.size(), dpnId);
836 * Get all termination points of type tunnel on a given DPN.
839 * Datapath Node Identifier
841 * @return If the data at the supplied path exists, returns a list of all termination point
842 * Augmentations of type tunnel
845 public List<OvsdbTerminationPointAugmentation> getTunnelPortsOnBridge(Uint64 dpnId) {
846 List<OvsdbTerminationPointAugmentation> tunnelPorts = new ArrayList<>();
847 Map<TerminationPointKey, TerminationPoint> portList = interfaceMetaUtils.getTerminationPointsOnBridge(dpnId);
848 for (TerminationPoint ovsPort : portList.values()) {
849 OvsdbTerminationPointAugmentation portAug =
850 ovsPort.augmentation(OvsdbTerminationPointAugmentation.class);
851 if (portAug != null && SouthboundUtils.isInterfaceTypeTunnel(portAug.getInterfaceType())) {
852 tunnelPorts.add(portAug);
856 LOG.debug("Found {} tunnel ports on bridge {}", tunnelPorts.size(), dpnId);
861 * Get all termination points by type on a given DPN.
864 * Datapath Node Identifier
866 * @return If the data at the supplied path exists, returns a Map where key is interfaceType
867 * and value is list of termination points of given type
870 public Map<Class<? extends InterfaceTypeBase>, List<OvsdbTerminationPointAugmentation>>
871 getPortsOnBridgeByType(Uint64 dpnId) {
873 Map<Class<? extends InterfaceTypeBase>, List<OvsdbTerminationPointAugmentation>> portMap;
874 portMap = new ConcurrentHashMap<>();
875 Map<TerminationPointKey, TerminationPoint> ovsPorts = interfaceMetaUtils.getTerminationPointsOnBridge(dpnId);
876 if (ovsPorts != null) {
877 for (TerminationPoint ovsPort : ovsPorts.values()) {
878 OvsdbTerminationPointAugmentation portAug =
879 ovsPort.augmentation(OvsdbTerminationPointAugmentation.class);
880 if (portAug != null && portAug.getInterfaceType() != null) {
881 portMap.computeIfAbsent(portAug.getInterfaceType(), k -> new ArrayList<>()).add(portAug);
889 public long getLogicalTunnelSelectGroupId(int lportTag) {
890 return IfmUtil.getLogicalTunnelSelectGroupId(lportTag);
894 public boolean isItmDirectTunnelsEnabled() {
895 return ifmConfig.isItmDirectTunnels();
899 public Map<Uint64, BridgeRefEntry> getBridgeRefEntryMap() {
900 return interfaceMetaUtils.getBridgeRefEntryMap();
904 public boolean isItmOfTunnelsEnabled() {
905 return ifmConfig.isItmOfTunnels();
909 public void addInternalTunnelToCache(String tunnelName, org.opendaylight.yang.gen.v1.urn.ietf.params
910 .xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface iface) {
911 internalTunnelCache.add(tunnelName,iface);
915 public org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces
916 .rev140508.interfaces.state.Interface getInternalTunnelCacheInfo(String tunnelName) {
917 return internalTunnelCache.get(tunnelName);
921 public org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces
922 .rev140508.interfaces.state.Interface removeInternalTunnelFromCache(String tunnelName) {
923 return internalTunnelCache.remove(tunnelName);