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.genius.infra.Datastore.CONFIGURATION;
11 import static org.opendaylight.mdsal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
13 import com.google.common.util.concurrent.ListenableFuture;
14 import java.util.ArrayList;
15 import java.util.Collections;
16 import java.util.List;
18 import java.util.concurrent.Callable;
19 import java.util.concurrent.ConcurrentHashMap;
20 import java.util.concurrent.ExecutionException;
21 import java.util.concurrent.Future;
22 import javax.annotation.PreDestroy;
23 import javax.inject.Inject;
24 import javax.inject.Singleton;
25 import org.apache.aries.blueprint.annotation.service.Reference;
26 import org.opendaylight.genius.datastoreutils.ExpectedDataObjectNotFoundException;
27 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
28 import org.opendaylight.genius.infra.Datastore.Configuration;
29 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
30 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
31 import org.opendaylight.genius.infra.TypedWriteTransaction;
32 import org.opendaylight.genius.interfacemanager.commons.InterfaceManagerCommonUtils;
33 import org.opendaylight.genius.interfacemanager.commons.InterfaceMetaUtils;
34 import org.opendaylight.genius.interfacemanager.diagstatus.IfmDiagStatusProvider;
35 import org.opendaylight.genius.interfacemanager.exceptions.InterfaceAlreadyExistsException;
36 import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo;
37 import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo.InterfaceAdminState;
38 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
39 import org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.SouthboundUtils;
40 import org.opendaylight.genius.interfacemanager.rpcservice.InterfaceManagerRpcService;
41 import org.opendaylight.genius.interfacemanager.servicebindings.flowbased.utilities.FlowBasedServicesUtils;
42 import org.opendaylight.genius.mdsalutil.ActionInfo;
43 import org.opendaylight.infrautils.diagstatus.ServiceState;
44 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
45 import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
46 import org.opendaylight.mdsal.binding.api.DataBroker;
47 import org.opendaylight.mdsal.binding.api.ReadTransaction;
48 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
49 import org.opendaylight.mdsal.eos.binding.api.Entity;
50 import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipCandidateRegistration;
51 import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipService;
52 import org.opendaylight.mdsal.eos.common.api.CandidateAlreadyRegisteredException;
53 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev170119.L2vlan;
54 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev170119.Tunnel;
55 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
56 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
57 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
58 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
59 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus;
60 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus;
61 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInput;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInputBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolOutput;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.config.rev160406.IfmConfig;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info.InterfaceParentEntry;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info._interface.parent.entry.InterfaceChildEntry;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfExternal;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfExternalBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlanBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefs;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefsBuilder;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEndpointIpForDpnInput;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEndpointIpForDpnInputBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEndpointIpForDpnOutput;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceInput;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceInputBuilder;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceOutput;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeBase;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeEgress;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeIngress;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServices;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeBase;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
93 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
94 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
95 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
96 import org.opendaylight.yangtools.yang.common.RpcResult;
97 import org.opendaylight.yangtools.yang.common.Uint64;
98 import org.slf4j.Logger;
99 import org.slf4j.LoggerFactory;
102 public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
103 private static final Logger LOG = LoggerFactory.getLogger(InterfacemgrProvider.class);
105 private final DataBroker dataBroker;
106 private final ManagedNewTransactionRunner txRunner;
107 private final IdManagerService idManager;
108 private final InterfaceManagerRpcService interfaceManagerRpcService;
109 private final EntityOwnershipService entityOwnershipService;
110 private final JobCoordinator coordinator;
111 private final InterfaceManagerCommonUtils interfaceManagerCommonUtils;
112 private final InterfaceMetaUtils interfaceMetaUtils;
113 private final IfmConfig ifmConfig;
114 private final IfmDiagStatusProvider ifmStatusProvider;
115 private Map<String, OvsdbTerminationPointAugmentation> ifaceToTpMap;
116 private Map<String, InstanceIdentifier<Node>> ifaceToNodeIidMap;
117 private Map<InstanceIdentifier<Node>, OvsdbBridgeAugmentation> nodeIidToBridgeMap;
118 private EntityOwnershipCandidateRegistration configEntityCandidate;
119 private EntityOwnershipCandidateRegistration bindingEntityCandidate;
122 public InterfacemgrProvider(@Reference final DataBroker dataBroker,
123 final EntityOwnershipService entityOwnershipService,
124 final IdManagerService idManager,
125 final InterfaceManagerRpcService interfaceManagerRpcService,
126 @Reference final JobCoordinator coordinator,
127 final InterfaceManagerCommonUtils interfaceManagerCommonUtils,
128 final InterfaceMetaUtils interfaceMetaUtils,
129 final IfmConfig ifmConfig,
130 final IfmDiagStatusProvider ifmStatusProvider) {
131 this.dataBroker = dataBroker;
132 this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
133 this.entityOwnershipService = entityOwnershipService;
134 this.idManager = idManager;
135 this.interfaceManagerRpcService = interfaceManagerRpcService;
136 this.coordinator = coordinator;
137 this.interfaceManagerCommonUtils = interfaceManagerCommonUtils;
138 this.interfaceMetaUtils = interfaceMetaUtils;
139 this.ifmConfig = ifmConfig;
140 this.ifmStatusProvider = ifmStatusProvider;
144 @SuppressWarnings("checkstyle:IllegalCatch")
145 public void start() {
148 configEntityCandidate = entityOwnershipService.registerCandidate(
149 new Entity(IfmConstants.INTERFACE_CONFIG_ENTITY, IfmConstants.INTERFACE_CONFIG_ENTITY));
150 bindingEntityCandidate = entityOwnershipService.registerCandidate(
151 new Entity(IfmConstants.INTERFACE_SERVICE_BINDING_ENTITY,
152 IfmConstants.INTERFACE_SERVICE_BINDING_ENTITY));
153 this.ifaceToTpMap = new ConcurrentHashMap<>();
154 this.ifaceToNodeIidMap = new ConcurrentHashMap<>();
155 this.nodeIidToBridgeMap = new ConcurrentHashMap<>();
156 ifmStatusProvider.reportStatus(ServiceState.OPERATIONAL);
157 LOG.info("InterfacemgrProvider Started");
158 } catch (CandidateAlreadyRegisteredException e) {
159 LOG.error("Failed to register entity {} with EntityOwnershipService", e.getEntity());
160 ifmStatusProvider.reportStatus(e);
161 } catch (InterruptedException | ExecutionException e) {
162 LOG.error("Failed to create idPool for InterfaceMgr", e);
168 public void close() throws Exception {
169 if (configEntityCandidate != null) {
170 configEntityCandidate.close();
173 if (bindingEntityCandidate != null) {
174 bindingEntityCandidate.close();
176 ifmStatusProvider.reportStatus(ServiceState.UNREGISTERED);
177 LOG.info("InterfacemgrProvider Closed");
180 public EntityOwnershipService getEntityOwnershipService() {
181 return entityOwnershipService;
184 public DataBroker getDataBroker() {
185 return this.dataBroker;
188 private void createIdPool() throws ExecutionException, InterruptedException {
189 CreateIdPoolInput createPool = new CreateIdPoolInputBuilder().setPoolName(IfmConstants.IFM_IDPOOL_NAME)
190 .setLow(IfmConstants.IFM_ID_POOL_START).setHigh(IfmConstants.IFM_ID_POOL_END).build();
191 // TODO: Error handling
192 ListenableFuture<RpcResult<CreateIdPoolOutput>> result = idManager.createIdPool(createPool);
193 if (result != null && result.get().isSuccessful()) {
194 LOG.debug("Created IdPool for InterfaceMgr");
199 public Long getPortForInterface(String ifName) {
200 GetPortFromInterfaceInput input = new GetPortFromInterfaceInputBuilder().setIntfName(ifName).build();
201 Future<RpcResult<GetPortFromInterfaceOutput>> output = interfaceManagerRpcService.getPortFromInterface(input);
203 RpcResult<GetPortFromInterfaceOutput> port = output.get();
204 if (port.isSuccessful()) {
205 return port.getResult().getPortno().toJava();
207 } catch (NullPointerException | InterruptedException | ExecutionException e) {
208 LOG.warn("Exception when getting port for interface", e);
214 public Long getPortForInterface(Interface intf) {
215 GetPortFromInterfaceInput input = new GetPortFromInterfaceInputBuilder().setIntfName(intf.getName()).build();
216 Future<RpcResult<GetPortFromInterfaceOutput>> output = interfaceManagerRpcService.getPortFromInterface(input);
218 RpcResult<GetPortFromInterfaceOutput> port = output.get();
219 if (port.isSuccessful()) {
220 return port.getResult().getPortno().toJava();
222 } catch (NullPointerException | InterruptedException | ExecutionException e) {
223 LOG.warn("Exception when getting port for interface", e);
229 public InterfaceInfo getInterfaceInfo(String interfaceName) {
231 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
232 .ietf.interfaces.rev140508.interfaces.state.Interface ifState = interfaceManagerCommonUtils
233 .getInterfaceState(interfaceName);
235 if (ifState == null) {
236 LOG.debug("Interface {} is not present", interfaceName);
240 Interface intf = interfaceManagerCommonUtils.getInterfaceFromConfigDS(new InterfaceKey(interfaceName));
242 LOG.warn("Interface {} doesn't exist in config datastore", interfaceName);
246 NodeConnectorId ncId = FlowBasedServicesUtils.getNodeConnectorIdFromInterface(intf.getName(),
247 interfaceManagerCommonUtils);
248 InterfaceInfo.InterfaceType interfaceType = IfmUtil.getInterfaceType(intf);
249 InterfaceInfo interfaceInfo = new InterfaceInfo(interfaceName);
250 Integer portNo = org.opendaylight.genius.interfacemanager.globals.IfmConstants.INVALID_PORT_NO;
253 dpId = IfmUtil.getDpnFromNodeConnectorId(ncId);
254 portNo = Integer.parseInt(IfmUtil.getPortNoFromNodeConnectorId(ncId));
258 if (interfaceType == InterfaceInfo.InterfaceType.VLAN_INTERFACE) {
259 interfaceInfo = IfmUtil.getVlanInterfaceInfo(intf, dpId);
260 } else if (interfaceType == InterfaceInfo.InterfaceType.UNKNOWN_INTERFACE) {
261 LOG.error("Type of Interface {} is unknown", interfaceName);
264 interfaceInfo.setDpId(dpId);
265 interfaceInfo.setPortNo(portNo);
266 interfaceInfo.setAdminState(intf.isEnabled() ? InterfaceAdminState.ENABLED : InterfaceAdminState.DISABLED);
267 interfaceInfo.setInterfaceName(interfaceName);
268 Integer lportTag = ifState.getIfIndex();
269 interfaceInfo.setInterfaceTag(lportTag);
270 interfaceInfo.setInterfaceType(interfaceType);
271 interfaceInfo.setGroupId(IfmUtil.getGroupId(lportTag, interfaceType));
272 interfaceInfo.setOpState(InterfaceInfo.InterfaceOpState.fromModel(ifState.getOperStatus()));
273 PhysAddress phyAddress = ifState.getPhysAddress();
274 if (phyAddress != null) {
275 interfaceInfo.setMacAddress(ifState.getPhysAddress().getValue());
278 return interfaceInfo;
283 public InterfaceInfo getInterfaceInfoFromOperationalDataStore(String interfaceName,
284 InterfaceInfo.InterfaceType interfaceType) {
285 InterfaceInfo interfaceInfo = new InterfaceInfo(interfaceName);
286 org.opendaylight.yang.gen.v1.urn
287 .ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState =
288 interfaceManagerCommonUtils.getInterfaceState(interfaceName);
289 if (ifState == null) {
290 LOG.debug("Interface {} is not present", interfaceName);
293 NodeConnectorId ncId = IfmUtil.getNodeConnectorIdFromInterface(ifState);
295 interfaceInfo.setDpId(IfmUtil.getDpnFromNodeConnectorId(ncId));
296 interfaceInfo.setPortNo(Integer.parseInt(IfmUtil.getPortNoFromNodeConnectorId(ncId)));
298 interfaceInfo.setAdminState(ifState.getAdminStatus() == AdminStatus.Up ? InterfaceAdminState.ENABLED
299 : InterfaceAdminState.DISABLED);
300 interfaceInfo.setInterfaceName(interfaceName);
301 Integer lportTag = ifState.getIfIndex();
302 interfaceInfo.setInterfaceTag(lportTag);
303 interfaceInfo.setInterfaceType(interfaceType);
304 interfaceInfo.setGroupId(IfmUtil.getGroupId(lportTag, interfaceType));
305 interfaceInfo.setOpState(InterfaceInfo.InterfaceOpState.fromModel(ifState.getOperStatus()));
306 PhysAddress phyAddress = ifState.getPhysAddress();
307 if (phyAddress != null) {
308 interfaceInfo.setMacAddress(ifState.getPhysAddress().getValue());
310 return interfaceInfo;
314 public InterfaceInfo getInterfaceInfoFromOperationalDataStore(String interfaceName) {
315 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
316 .ietf.interfaces.rev140508.interfaces.state.Interface ifState = interfaceManagerCommonUtils
317 .getInterfaceState(interfaceName);
318 if (ifState == null) {
319 LOG.debug("Interface {} is not present", interfaceName);
323 return populateInterfaceInfo(interfaceName, ifState);
326 public InterfaceInfo populateInterfaceInfo(String interfaceName,
327 org.opendaylight.yang.gen.v1.urn
328 .ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState) {
329 InterfaceInfo interfaceInfo = new InterfaceInfo(interfaceName);
330 NodeConnectorId ncId = IfmUtil.getNodeConnectorIdFromInterface(ifState);
332 if (Tunnel.class.equals(ifState.getType())) {
333 interfaceInfo.setPortName(interfaceName);
335 Interface iface = interfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceName);
337 ParentRefs parentRefs = iface.augmentation(ParentRefs.class);
338 interfaceInfo.setPortName(parentRefs.getParentInterface());
341 interfaceInfo.setDpId(IfmUtil.getDpnFromNodeConnectorId(ncId));
342 interfaceInfo.setPortNo(Integer.parseInt(IfmUtil.getPortNoFromNodeConnectorId(ncId)));
344 interfaceInfo.setAdminState(ifState.getAdminStatus() == AdminStatus.Up ? InterfaceAdminState.ENABLED
345 : InterfaceAdminState.DISABLED);
346 interfaceInfo.setInterfaceName(interfaceName);
347 Integer lportTag = ifState.getIfIndex();
348 if (lportTag != null) {
349 interfaceInfo.setInterfaceTag(lportTag);
351 interfaceInfo.setOpState(InterfaceInfo.InterfaceOpState.fromModel(ifState.getOperStatus()));
352 PhysAddress phyAddress = ifState.getPhysAddress();
353 if (phyAddress != null) {
354 interfaceInfo.setMacAddress(ifState.getPhysAddress().getValue());
356 return interfaceInfo;
360 public InterfaceInfo getInterfaceInfoFromOperationalDSCache(String interfaceName) {
361 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
362 .ietf.interfaces.rev140508.interfaces.state.Interface ifState = interfaceManagerCommonUtils
363 .getInterfaceStateFromCache(interfaceName);
364 if (ifState == null) {
365 LOG.warn("Interface {} is not present", interfaceName);
368 return populateInterfaceInfo(interfaceName, ifState);
372 public Interface getInterfaceInfoFromConfigDataStore(String interfaceName) {
373 return interfaceManagerCommonUtils.getInterfaceFromConfigDS(new InterfaceKey(interfaceName));
377 public Interface getInterfaceInfoFromConfigDataStore(ReadTransaction tx, String interfaceName)
378 throws ExecutionException, InterruptedException {
379 return interfaceManagerCommonUtils.getInterfaceFromConfigDS(tx, new InterfaceKey(interfaceName));
383 public void createVLANInterface(String interfaceName, String portName, Uint64 dpId, Integer vlanId,
384 String description, IfL2vlan.L2vlanMode l2vlanMode) throws InterfaceAlreadyExistsException {
385 createVLANInterface(interfaceName, portName, vlanId, description, l2vlanMode);
389 public ListenableFuture<Void> createVLANInterface(String interfaceName, String portName, Integer vlanId,
390 String description, IfL2vlan.L2vlanMode l2vlanMode) throws InterfaceAlreadyExistsException {
391 return createVLANInterface(interfaceName, portName, vlanId, description, l2vlanMode, false);
395 public void createVLANInterface(String interfaceName, String portName, Uint64 dpId, Integer vlanId,
396 String description, IfL2vlan.L2vlanMode l2vlanMode, boolean isExternal)
397 throws InterfaceAlreadyExistsException {
398 createVLANInterface(interfaceName, portName, vlanId, description, l2vlanMode, isExternal);
402 public ListenableFuture<Void> createVLANInterface(String interfaceName, String portName, Integer vlanId,
403 String description, IfL2vlan.L2vlanMode l2vlanMode,
405 throws InterfaceAlreadyExistsException {
407 LOG.info("Create VLAN interface : {}", interfaceName);
408 Interface interfaceOptional = interfaceManagerCommonUtils
409 .getInterfaceFromConfigDS(new InterfaceKey(interfaceName));
410 if (interfaceOptional != null) {
411 LOG.debug("VLAN interface already exists {} ", interfaceOptional.getDescription());
412 throw new InterfaceAlreadyExistsException(interfaceOptional.getName());
414 IfL2vlanBuilder l2vlanBuilder = new IfL2vlanBuilder().setL2vlanMode(l2vlanMode);
415 if (vlanId != null && vlanId > 0) {
416 l2vlanBuilder.setVlanId(new VlanId(vlanId));
418 ParentRefs parentRefs = new ParentRefsBuilder().setParentInterface(portName).build();
419 InterfaceBuilder interfaceBuilder = new InterfaceBuilder().setEnabled(true).setName(interfaceName)
420 .setType(L2vlan.class).addAugmentation(IfL2vlan.class, l2vlanBuilder.build())
421 .addAugmentation(ParentRefs.class, parentRefs).setDescription(description);
423 interfaceBuilder.addAugmentation(IfExternal.class, new IfExternalBuilder().setExternal(true).build());
425 InstanceIdentifier<Interface> interfaceIId = InterfaceManagerCommonUtils
426 .getInterfaceIdentifier(new InterfaceKey(interfaceName));
427 ListenableFuture<Void> future = txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
428 tx -> tx.put(interfaceIId, interfaceBuilder.build(), CREATE_MISSING_PARENTS));
429 ListenableFutures.addErrorLogging(future, LOG, "Failed to (async) write {}", interfaceIId);
433 private boolean isServiceBoundOnInterface(short servicePriority, String interfaceName,
434 Class<? extends ServiceModeBase> serviceMode) {
435 InstanceIdentifier<BoundServices> boundServicesIId = IfmUtil.buildBoundServicesIId(servicePriority,
436 interfaceName, serviceMode);
438 return SingleTransactionDataBroker
439 .syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION, boundServicesIId).isPresent();
440 } catch (ExecutionException | InterruptedException e) {
441 LOG.warn("Error while reading [{}]", boundServicesIId, e);
447 public boolean isServiceBoundOnInterfaceForIngress(short servicePriority, String interfaceName) {
448 return isServiceBoundOnInterface(servicePriority, interfaceName, ServiceModeIngress.class);
452 public boolean isServiceBoundOnInterfaceForEgress(short servicePriority, String interfaceName) {
453 return isServiceBoundOnInterface(servicePriority, interfaceName, ServiceModeEgress.class);
457 public void bindService(String interfaceName, Class<? extends ServiceModeBase> serviceMode,
458 BoundServices serviceInfo) {
459 bindService(interfaceName, serviceMode, serviceInfo, /* WriteTransaction */ null);
463 public void bindService(String interfaceName, Class<? extends ServiceModeBase> serviceMode,
464 BoundServices serviceInfo, TypedWriteTransaction<Configuration> tx) {
466 ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
467 wtx -> IfmUtil.bindService(wtx, interfaceName, serviceInfo, serviceMode)), LOG,
468 "Error binding the InterfacemgrProvider service");
470 IfmUtil.bindService(tx, interfaceName, serviceInfo, serviceMode);
475 public void unbindService(String interfaceName, Class<? extends ServiceModeBase> serviceMode,
476 BoundServices serviceInfo) {
477 IfmUtil.unbindService(txRunner, coordinator, interfaceName,
478 FlowBasedServicesUtils.buildServiceId(interfaceName,
479 serviceInfo.getServicePriority().toJava(), serviceMode));
483 public Uint64 getDpnForInterface(Interface intrf) {
484 return getDpnForInterface(intrf.getName());
488 public Uint64 getDpnForInterface(String ifName) {
489 GetDpidFromInterfaceInput input = new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
490 Future<RpcResult<GetDpidFromInterfaceOutput>> output = interfaceManagerRpcService.getDpidFromInterface(input);
492 RpcResult<GetDpidFromInterfaceOutput> dpn = output.get();
493 if (dpn.isSuccessful()) {
494 return dpn.getResult().getDpid();
496 } catch (NullPointerException | InterruptedException | ExecutionException e) {
497 LOG.warn("Exception when getting port for interface", e);
503 public String getEndpointIpForDpn(Uint64 dpnId) {
504 GetEndpointIpForDpnInput input = new GetEndpointIpForDpnInputBuilder().setDpid(dpnId).build();
505 Future<RpcResult<GetEndpointIpForDpnOutput>> output = interfaceManagerRpcService.getEndpointIpForDpn(input);
507 RpcResult<GetEndpointIpForDpnOutput> ipForDpnOutputRpcResult = output.get();
508 if (ipForDpnOutputRpcResult.isSuccessful()) {
509 List<IpAddress> localIps = ipForDpnOutputRpcResult.getResult().getLocalIps();
510 if (localIps != null && !localIps.isEmpty()) {
511 return localIps.get(0).getIpv4Address().getValue();
514 } catch (NullPointerException | InterruptedException | ExecutionException e) {
515 LOG.warn("Exception when getting port for interface", e);
521 public List<ActionInfo> getInterfaceEgressActions(String ifName) {
522 return IfmUtil.getEgressActionInfosForInterface(ifName, 0, interfaceManagerCommonUtils, false);
526 public List<Interface> getVlanInterfaces() {
527 return interfaceManagerCommonUtils.getAllVlanInterfacesFromCache();
531 public List<Interface> getVxlanInterfaces() {
532 return interfaceManagerCommonUtils.getAllTunnelInterfacesFromCache();
536 public List<Interface> getChildInterfaces(String parentInterface) {
537 try (ReadTransaction tx = dataBroker.newReadOnlyTransaction()) {
538 return getChildInterfaces(tx, parentInterface);
539 } catch (ExecutionException | InterruptedException e) {
540 LOG.error("Error retrieving child interfaces of {} from config", parentInterface, e);
541 throw new RuntimeException("Error retrieving child interfaces of " + parentInterface + " from config", e);
546 public List<Interface> getChildInterfaces(ReadTransaction tx, String parentInterface) throws
547 ExecutionException, InterruptedException {
548 InterfaceParentEntry parentEntry = interfaceMetaUtils.getInterfaceParentEntryFromConfigDS(tx, parentInterface);
549 if (parentEntry == null) {
550 LOG.debug("No parent entry found for {}", parentInterface);
551 return Collections.emptyList();
554 List<InterfaceChildEntry> childEntries = parentEntry.getInterfaceChildEntry();
555 if (childEntries == null || childEntries.isEmpty()) {
556 LOG.debug("No child entries found for parent {}", parentInterface);
557 return Collections.emptyList();
560 List<Interface> childInterfaces = new ArrayList<>();
561 for (InterfaceChildEntry childEntry : childEntries) {
562 String interfaceName = childEntry.getChildInterface();
563 Interface iface = interfaceManagerCommonUtils.getInterfaceFromConfigDS(tx, interfaceName);
565 childInterfaces.add(iface);
567 LOG.debug("Child interface {} not found in config DS for parent interface {}", interfaceName,
572 LOG.trace("Found child interfaces {} for parent {}", childInterfaces, parentInterface);
573 return childInterfaces;
577 public boolean isExternalInterface(String interfaceName) {
578 return isExternalInterface(getInterfaceInfoFromConfigDataStore(interfaceName));
582 public boolean isExternalInterface(ReadTransaction tx, String interfaceName) throws
583 ExecutionException, InterruptedException {
584 return isExternalInterface(getInterfaceInfoFromConfigDataStore(tx, interfaceName));
587 private boolean isExternalInterface(Interface iface) {
592 IfExternal ifExternal = iface.augmentation(IfExternal.class);
593 return ifExternal != null && Boolean.TRUE.equals(ifExternal.isExternal());
597 public String getPortNameForInterface(NodeConnectorId nodeConnectorId, String interfaceName) {
598 return InterfaceManagerCommonUtils.getPortNameForInterface(nodeConnectorId, interfaceName);
602 public String getPortNameForInterface(String dpnId, String interfaceName) {
603 return InterfaceManagerCommonUtils.getPortNameForInterface(dpnId, interfaceName);
607 public Map<String, OvsdbTerminationPointAugmentation> getTerminationPointCache() {
608 return new ConcurrentHashMap<>(this.ifaceToTpMap);
612 public Map<String, OperStatus> getBfdStateCache() {
613 return interfaceManagerCommonUtils.getBfdStateMap();
616 public void addTerminationPointForInterface(String interfaceName,
617 OvsdbTerminationPointAugmentation terminationPoint) {
618 if (interfaceName != null && terminationPoint != null) {
619 LOG.debug("Adding TerminationPoint {} to cache for Interface {}", terminationPoint.getName(),
621 ifaceToTpMap.put(interfaceName, terminationPoint);
625 public OvsdbTerminationPointAugmentation getTerminationPoint(String interfaceName) {
626 return ifaceToTpMap.get(interfaceName);
629 public void removeTerminationPointForInterface(String interfaceName) {
630 LOG.debug("Removing TerminationPoint from cache for Interface {}", interfaceName);
631 if (interfaceName != null) {
632 ifaceToTpMap.remove(interfaceName);
636 public void addNodeIidForInterface(String interfaceName, InstanceIdentifier<Node> nodeIid) {
637 if (interfaceName != null && nodeIid != null) {
638 ifaceToNodeIidMap.put(interfaceName, nodeIid);
642 public void removeNodeIidForInterface(String interfaceName) {
643 if (interfaceName != null) {
644 ifaceToNodeIidMap.remove(interfaceName);
648 public InstanceIdentifier<Node> getNodeIidForInterface(String interfaceName) {
649 if (interfaceName != null) {
650 return ifaceToNodeIidMap.get(interfaceName);
655 private OvsdbBridgeAugmentation getBridgeForInterface(String interfaceName,
656 InstanceIdentifier<Node> nodeInstanceId) {
657 InstanceIdentifier<Node> nodeIid = nodeInstanceId;
658 if (nodeIid == null) {
659 nodeIid = getNodeIidForInterface(interfaceName);
661 return getBridgeForNodeIid(nodeIid);
664 public String getDpidForInterface(String interfaceName) {
665 return getDpidForInterface(interfaceName, null);
668 public String getDpidForInterface(String interfaceName, InstanceIdentifier<Node> nodeInstanceId) {
669 OvsdbBridgeAugmentation bridge = getBridgeForInterface(interfaceName, nodeInstanceId);
670 if (bridge != null) {
671 Uint64 dpid = IfmUtil.getDpnId(bridge.getDatapathId());
672 if (dpid != null && dpid.longValue() != 0) {
673 return String.valueOf(dpid);
679 public void addBridgeForNodeIid(InstanceIdentifier<Node> nodeIid, OvsdbBridgeAugmentation bridge) {
680 if (nodeIid != null && bridge != null) {
681 nodeIidToBridgeMap.put(nodeIid, bridge);
685 public void removeBridgeForNodeIid(InstanceIdentifier<Node> nodeIid) {
686 if (nodeIid != null) {
687 nodeIidToBridgeMap.remove(nodeIid);
691 public OvsdbBridgeAugmentation getBridgeForNodeIid(InstanceIdentifier<Node> nodeIid) {
692 if (nodeIid == null) {
696 OvsdbBridgeAugmentation ret = nodeIidToBridgeMap.get(nodeIid);
701 LOG.info("Node {} not found in cache, reading from md-sal", nodeIid);
704 node = SingleTransactionDataBroker.syncRead(
705 dataBroker, LogicalDatastoreType.OPERATIONAL, nodeIid);
706 } catch (ExpectedDataObjectNotFoundException e) {
707 LOG.error("Failed to read Node for {} ", nodeIid, e);
711 OvsdbBridgeAugmentation bridge = node.augmentation(OvsdbBridgeAugmentation.class);
712 if (bridge == null) {
713 LOG.error("Node {} has no bridge augmentation", nodeIid);
717 addBridgeForNodeIid(nodeIid, bridge);
722 public String getParentRefNameForInterface(String interfaceName) {
723 String parentRefName = null;
725 String dpnId = getDpidForInterface(interfaceName, null);
726 OvsdbTerminationPointAugmentation ovsdbTp = getTerminationPoint(interfaceName);
727 if (ovsdbTp != null) {
729 LOG.error("Got NULL dpnId when looking for TP with external ID {}", interfaceName);
732 parentRefName = getPortNameForInterface(dpnId, ovsdbTp.getName());
733 LOG.debug("Building parent ref for interface {}, using parentRefName {} acquired by external ID",
734 interfaceName, parentRefName);
736 LOG.debug("Skipping parent ref for interface {}, as there is no termination point that references "
737 + "this interface yet.", interfaceName);
740 return parentRefName;
744 public void updateInterfaceParentRef(String interfaceName, String parentInterface) {
745 // This should generally be called by EOS Owner for
746 // INTERFACE_CONFIG_ENTITY - runOnlyInLeaderNode()
747 updateInterfaceParentRef(interfaceName, parentInterface, true);
751 public void updateInterfaceParentRef(String interfaceName, String parentInterface,
752 boolean readInterfaceBeforeWrite) {
753 // This should generally be called by EOS Owner for
754 // INTERFACE_CONFIG_ENTITY - runOnlyInLeaderNode()
755 if (interfaceName == null) {
759 ParentRefUpdateWorker parentRefUpdateWorker = new ParentRefUpdateWorker(interfaceName, parentInterface,
760 readInterfaceBeforeWrite);
761 coordinator.enqueueJob(interfaceName, parentRefUpdateWorker, IfmConstants.JOB_MAX_RETRIES);
764 public class ParentRefUpdateWorker implements Callable<List<? extends ListenableFuture<?>>> {
765 String interfaceName;
766 String parentInterfaceName;
767 Boolean readInterfaceBeforeWrite;
769 public ParentRefUpdateWorker(String interfaceName, String parentInterfaceName,
770 boolean readInterfaceBeforeWrite) {
771 this.interfaceName = interfaceName;
772 this.parentInterfaceName = parentInterfaceName;
773 this.readInterfaceBeforeWrite = readInterfaceBeforeWrite;
777 public List<ListenableFuture<Void>> call() {
778 if (readInterfaceBeforeWrite) {
779 Interface iface = interfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceName);
781 LOG.debug("Interface doesn't exist in config DS - no need to update parentRef, skipping");
785 return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
786 tx -> IfmUtil.updateInterfaceParentRef(tx, interfaceName, parentInterfaceName)));
791 public OvsdbTerminationPointAugmentation getTerminationPointForInterface(String interfaceName) {
792 return getTerminationPoint(interfaceName);
796 public OvsdbBridgeAugmentation getOvsdbBridgeForInterface(String interfaceName) {
797 return getBridgeForInterface(interfaceName, null);
801 public OvsdbBridgeAugmentation getOvsdbBridgeForNodeIid(InstanceIdentifier<Node> nodeIid) {
802 return getBridgeForNodeIid(nodeIid);
807 * Get all termination points on a given DPN.
808 * This API uses read on Operational DS. If there are perf issues in cluster
809 * setup, we can consider caching later.
812 * Datapath Node Identifier
814 * @return If the data at the supplied path exists, returns a list of all termination point
817 public List<OvsdbTerminationPointAugmentation> getPortsOnBridge(Uint64 dpnId) {
818 List<OvsdbTerminationPointAugmentation> ports = new ArrayList<>();
819 List<TerminationPoint> portList = interfaceMetaUtils.getTerminationPointsOnBridge(dpnId);
820 for (TerminationPoint ovsPort : portList) {
821 if (ovsPort.augmentation(OvsdbTerminationPointAugmentation.class) != null) {
822 ports.add(ovsPort.augmentation(OvsdbTerminationPointAugmentation.class));
825 LOG.debug("Found {} ports on bridge {}", ports.size(), dpnId);
830 * Get all termination points of type tunnel on a given DPN.
833 * Datapath Node Identifier
835 * @return If the data at the supplied path exists, returns a list of all termination point
836 * Augmentations of type tunnel
839 public List<OvsdbTerminationPointAugmentation> getTunnelPortsOnBridge(Uint64 dpnId) {
840 List<OvsdbTerminationPointAugmentation> tunnelPorts = new ArrayList<>();
841 List<TerminationPoint> portList = interfaceMetaUtils.getTerminationPointsOnBridge(dpnId);
842 for (TerminationPoint ovsPort : portList) {
843 OvsdbTerminationPointAugmentation portAug =
844 ovsPort.augmentation(OvsdbTerminationPointAugmentation.class);
845 if (portAug != null && SouthboundUtils.isInterfaceTypeTunnel(portAug.getInterfaceType())) {
846 tunnelPorts.add(portAug);
850 LOG.debug("Found {} tunnel ports on bridge {}", tunnelPorts.size(), dpnId);
855 * Get all termination points by type on a given DPN.
858 * Datapath Node Identifier
860 * @return If the data at the supplied path exists, returns a Map where key is interfaceType
861 * and value is list of termination points of given type
864 public Map<Class<? extends InterfaceTypeBase>, List<OvsdbTerminationPointAugmentation>>
865 getPortsOnBridgeByType(Uint64 dpnId) {
867 Map<Class<? extends InterfaceTypeBase>, List<OvsdbTerminationPointAugmentation>> portMap;
868 portMap = new ConcurrentHashMap<>();
869 List<TerminationPoint> ovsPorts = interfaceMetaUtils.getTerminationPointsOnBridge(dpnId);
870 if (ovsPorts != null) {
871 for (TerminationPoint ovsPort : ovsPorts) {
872 OvsdbTerminationPointAugmentation portAug =
873 ovsPort.augmentation(OvsdbTerminationPointAugmentation.class);
874 if (portAug != null && portAug.getInterfaceType() != null) {
875 portMap.computeIfAbsent(portAug.getInterfaceType(), k -> new ArrayList<>()).add(portAug);
883 public long getLogicalTunnelSelectGroupId(int lportTag) {
884 return IfmUtil.getLogicalTunnelSelectGroupId(lportTag);
888 public boolean isItmDirectTunnelsEnabled() {
889 return ifmConfig.isItmDirectTunnels();
893 public Map getBridgeRefEntryMap() {
894 return interfaceMetaUtils.getBridgeRefEntryMap();