2 * Copyright (c) 2016, 2017 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 com.google.common.util.concurrent.ListenableFuture;
11 import java.math.BigInteger;
12 import java.util.ArrayList;
13 import java.util.Collections;
14 import java.util.List;
16 import java.util.concurrent.Callable;
17 import java.util.concurrent.ConcurrentHashMap;
18 import java.util.concurrent.ExecutionException;
19 import java.util.concurrent.Future;
20 import javax.annotation.PostConstruct;
21 import javax.annotation.PreDestroy;
22 import javax.inject.Inject;
23 import javax.inject.Singleton;
24 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
25 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
26 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
27 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
28 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
29 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
30 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
31 import org.opendaylight.genius.interfacemanager.commons.InterfaceManagerCommonUtils;
32 import org.opendaylight.genius.interfacemanager.commons.InterfaceMetaUtils;
33 import org.opendaylight.genius.interfacemanager.exceptions.InterfaceAlreadyExistsException;
34 import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo;
35 import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo.InterfaceAdminState;
36 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
37 import org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.BatchingUtils;
38 import org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.SouthboundUtils;
39 import org.opendaylight.genius.interfacemanager.rpcservice.InterfaceManagerRpcService;
40 import org.opendaylight.genius.interfacemanager.servicebindings.flowbased.utilities.FlowBasedServicesUtils;
41 import org.opendaylight.genius.interfacemanager.statusanddiag.InterfaceStatusMonitor;
42 import org.opendaylight.genius.mdsalutil.ActionInfo;
43 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
44 import org.opendaylight.mdsal.eos.binding.api.Entity;
45 import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipCandidateRegistration;
46 import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipService;
47 import org.opendaylight.mdsal.eos.common.api.CandidateAlreadyRegisteredException;
48 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan;
49 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel;
50 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
51 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
52 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
53 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
54 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus;
55 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus;
56 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInput;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInputBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info.InterfaceParentEntry;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info._interface.parent.entry.InterfaceChildEntry;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfExternal;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfExternalBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlanBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefs;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefsBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEndpointIpForDpnInput;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEndpointIpForDpnInputBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEndpointIpForDpnOutput;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceInput;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceInputBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceOutput;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeBase;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeEgress;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeIngress;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServices;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeBase;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
86 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
87 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
88 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
89 import org.opendaylight.yangtools.yang.common.RpcResult;
90 import org.slf4j.Logger;
91 import org.slf4j.LoggerFactory;
94 public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
95 private static final Logger LOG = LoggerFactory.getLogger(InterfacemgrProvider.class);
97 private final DataBroker dataBroker;
98 private final ManagedNewTransactionRunner txRunner;
99 private final IdManagerService idManager;
100 private final InterfaceManagerRpcService interfaceManagerRpcService;
101 private final EntityOwnershipService entityOwnershipService;
102 private final JobCoordinator coordinator;
103 private final InterfaceManagerCommonUtils interfaceManagerCommonUtils;
104 private final InterfaceStatusMonitor interfaceStatusMonitor = new InterfaceStatusMonitor();
105 private Map<String, OvsdbTerminationPointAugmentation> ifaceToTpMap;
106 private Map<String, InstanceIdentifier<Node>> ifaceToNodeIidMap;
107 private Map<InstanceIdentifier<Node>, OvsdbBridgeAugmentation> nodeIidToBridgeMap;
108 private EntityOwnershipCandidateRegistration configEntityCandidate;
109 private EntityOwnershipCandidateRegistration bindingEntityCandidate;
112 public InterfacemgrProvider(final DataBroker dataBroker, final EntityOwnershipService entityOwnershipService,
113 final IdManagerService idManager, final InterfaceManagerRpcService interfaceManagerRpcService,
114 final JobCoordinator coordinator, final InterfaceManagerCommonUtils interfaceManagerCommonUtils) {
115 this.dataBroker = dataBroker;
116 this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
117 this.entityOwnershipService = entityOwnershipService;
118 this.idManager = idManager;
119 this.interfaceManagerRpcService = interfaceManagerRpcService;
120 this.coordinator = coordinator;
121 this.interfaceManagerCommonUtils = interfaceManagerCommonUtils;
125 @SuppressWarnings("checkstyle:IllegalCatch")
126 public void start() {
128 interfaceStatusMonitor.registerMbean();
132 configEntityCandidate = entityOwnershipService.registerCandidate(
133 new Entity(IfmConstants.INTERFACE_CONFIG_ENTITY, IfmConstants.INTERFACE_CONFIG_ENTITY));
134 bindingEntityCandidate = entityOwnershipService.registerCandidate(
135 new Entity(IfmConstants.INTERFACE_SERVICE_BINDING_ENTITY,
136 IfmConstants.INTERFACE_SERVICE_BINDING_ENTITY));
137 } catch (CandidateAlreadyRegisteredException e) {
138 LOG.error("Failed to register entity {} with EntityOwnershipService", e.getEntity());
141 BatchingUtils.registerWithBatchManager(this.dataBroker);
142 this.ifaceToTpMap = new ConcurrentHashMap<>();
143 this.ifaceToNodeIidMap = new ConcurrentHashMap<>();
144 this.nodeIidToBridgeMap = new ConcurrentHashMap<>();
146 interfaceStatusMonitor.reportStatus("OPERATIONAL");
147 } catch (Exception e) {
148 interfaceStatusMonitor.reportStatus("ERROR");
151 LOG.info("InterfacemgrProvider Started");
156 public void close() throws Exception {
157 interfaceStatusMonitor.unregisterMbean();
159 if (configEntityCandidate != null) {
160 configEntityCandidate.close();
163 if (bindingEntityCandidate != null) {
164 bindingEntityCandidate.close();
167 LOG.info("InterfacemgrProvider Closed");
170 public EntityOwnershipService getEntityOwnershipService() {
171 return entityOwnershipService;
174 public DataBroker getDataBroker() {
175 return this.dataBroker;
178 private void createIdPool() {
179 CreateIdPoolInput createPool = new CreateIdPoolInputBuilder().setPoolName(IfmConstants.IFM_IDPOOL_NAME)
180 .setLow(IfmConstants.IFM_ID_POOL_START).setHigh(IfmConstants.IFM_ID_POOL_END).build();
181 // TODO: Error handling
182 Future<RpcResult<Void>> result = idManager.createIdPool(createPool);
184 if (result != null && result.get().isSuccessful()) {
185 LOG.debug("Created IdPool for InterfaceMgr");
187 } catch (InterruptedException | ExecutionException e) {
188 LOG.error("Failed to create idPool for InterfaceMgr", e);
193 public Long getPortForInterface(String ifName) {
194 GetPortFromInterfaceInput input = new GetPortFromInterfaceInputBuilder().setIntfName(ifName).build();
195 Future<RpcResult<GetPortFromInterfaceOutput>> output = interfaceManagerRpcService.getPortFromInterface(input);
197 RpcResult<GetPortFromInterfaceOutput> port = output.get();
198 if (port.isSuccessful()) {
199 return port.getResult().getPortno();
201 } catch (NullPointerException | InterruptedException | ExecutionException e) {
202 LOG.warn("Exception when getting port for interface", e);
208 public Long getPortForInterface(Interface intf) {
209 GetPortFromInterfaceInput input = new GetPortFromInterfaceInputBuilder().setIntfName(intf.getName()).build();
210 Future<RpcResult<GetPortFromInterfaceOutput>> output = interfaceManagerRpcService.getPortFromInterface(input);
212 RpcResult<GetPortFromInterfaceOutput> port = output.get();
213 if (port.isSuccessful()) {
214 return port.getResult().getPortno();
216 } catch (NullPointerException | InterruptedException | ExecutionException e) {
217 LOG.warn("Exception when getting port for interface", e);
223 public InterfaceInfo getInterfaceInfo(String interfaceName) {
225 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
226 .ietf.interfaces.rev140508.interfaces.state.Interface ifState = interfaceManagerCommonUtils
227 .getInterfaceState(interfaceName);
229 if (ifState == null) {
230 LOG.debug("Interface {} is not present", interfaceName);
234 Interface intf = interfaceManagerCommonUtils.getInterfaceFromConfigDS(new InterfaceKey(interfaceName));
236 LOG.error("Interface {} doesn't exist in config datastore", interfaceName);
240 NodeConnectorId ncId = FlowBasedServicesUtils.getNodeConnectorIdFromInterface(intf.getName(),
241 interfaceManagerCommonUtils);
242 InterfaceInfo.InterfaceType interfaceType = IfmUtil.getInterfaceType(intf);
243 InterfaceInfo interfaceInfo = new InterfaceInfo(interfaceName);
244 BigInteger dpId = org.opendaylight.genius.interfacemanager.globals.IfmConstants.INVALID_DPID;
245 Integer portNo = org.opendaylight.genius.interfacemanager.globals.IfmConstants.INVALID_PORT_NO;
247 dpId = IfmUtil.getDpnFromNodeConnectorId(ncId);
248 portNo = Integer.parseInt(IfmUtil.getPortNoFromNodeConnectorId(ncId));
250 if (interfaceType == InterfaceInfo.InterfaceType.VLAN_INTERFACE) {
251 interfaceInfo = IfmUtil.getVlanInterfaceInfo(intf, dpId);
252 } else if (interfaceType == InterfaceInfo.InterfaceType.UNKNOWN_INTERFACE) {
253 LOG.error("Type of Interface {} is unknown", interfaceName);
256 InterfaceInfo.InterfaceOpState opState;
257 if (ifState.getOperStatus() == OperStatus.Up) {
258 opState = InterfaceInfo.InterfaceOpState.UP;
259 } else if (ifState.getOperStatus() == OperStatus.Down) {
260 opState = InterfaceInfo.InterfaceOpState.DOWN;
262 opState = InterfaceInfo.InterfaceOpState.UNKNOWN;
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(opState);
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.InterfaceOpState opState;
299 if (ifState.getOperStatus() == OperStatus.Up) {
300 opState = InterfaceInfo.InterfaceOpState.UP;
301 } else if (ifState.getOperStatus() == OperStatus.Down) {
302 opState = InterfaceInfo.InterfaceOpState.DOWN;
304 opState = InterfaceInfo.InterfaceOpState.UNKNOWN;
306 interfaceInfo.setAdminState(ifState.getAdminStatus() == AdminStatus.Up ? InterfaceAdminState.ENABLED
307 : InterfaceAdminState.DISABLED);
308 interfaceInfo.setInterfaceName(interfaceName);
309 Integer lportTag = ifState.getIfIndex();
310 interfaceInfo.setInterfaceTag(lportTag);
311 interfaceInfo.setInterfaceType(interfaceType);
312 interfaceInfo.setGroupId(IfmUtil.getGroupId(lportTag, interfaceType));
313 interfaceInfo.setOpState(opState);
314 PhysAddress phyAddress = ifState.getPhysAddress();
315 if (phyAddress != null) {
316 interfaceInfo.setMacAddress(ifState.getPhysAddress().getValue());
318 return interfaceInfo;
322 public InterfaceInfo getInterfaceInfoFromOperationalDataStore(String interfaceName) {
323 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
324 .ietf.interfaces.rev140508.interfaces.state.Interface ifState = interfaceManagerCommonUtils
325 .getInterfaceState(interfaceName);
326 if (ifState == null) {
327 LOG.debug("Interface {} is not present", interfaceName);
331 return populateInterfaceInfo(interfaceName, ifState);
334 public InterfaceInfo populateInterfaceInfo(String interfaceName,
335 org.opendaylight.yang.gen.v1.urn
336 .ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState) {
337 InterfaceInfo interfaceInfo = new InterfaceInfo(interfaceName);
338 NodeConnectorId ncId = IfmUtil.getNodeConnectorIdFromInterface(ifState);
340 if (Tunnel.class.equals(ifState.getType())) {
341 interfaceInfo.setPortName(interfaceName);
343 Interface iface = interfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceName);
345 ParentRefs parentRefs = iface.getAugmentation(ParentRefs.class);
346 interfaceInfo.setPortName(parentRefs.getParentInterface());
349 interfaceInfo.setDpId(IfmUtil.getDpnFromNodeConnectorId(ncId));
350 interfaceInfo.setPortNo(Integer.parseInt(IfmUtil.getPortNoFromNodeConnectorId(ncId)));
352 InterfaceInfo.InterfaceOpState opState;
353 if (ifState.getOperStatus() == OperStatus.Up) {
354 opState = InterfaceInfo.InterfaceOpState.UP;
355 } else if (ifState.getOperStatus() == OperStatus.Down) {
356 opState = InterfaceInfo.InterfaceOpState.DOWN;
358 opState = InterfaceInfo.InterfaceOpState.UNKNOWN;
360 interfaceInfo.setAdminState(ifState.getAdminStatus() == AdminStatus.Up ? InterfaceAdminState.ENABLED
361 : InterfaceAdminState.DISABLED);
362 interfaceInfo.setInterfaceName(interfaceName);
363 Integer lportTag = ifState.getIfIndex();
364 if (lportTag != null) {
365 interfaceInfo.setInterfaceTag(lportTag);
367 interfaceInfo.setOpState(opState);
368 PhysAddress phyAddress = ifState.getPhysAddress();
369 if (phyAddress != null) {
370 interfaceInfo.setMacAddress(ifState.getPhysAddress().getValue());
372 return interfaceInfo;
376 public InterfaceInfo getInterfaceInfoFromOperationalDSCache(String interfaceName) {
377 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
378 .ietf.interfaces.rev140508.interfaces.state.Interface ifState = interfaceManagerCommonUtils
379 .getInterfaceStateFromCache(interfaceName);
380 if (ifState == null) {
381 LOG.warn("Interface {} is not present", interfaceName);
384 return populateInterfaceInfo(interfaceName, ifState);
388 public Interface getInterfaceInfoFromConfigDataStore(String interfaceName) {
389 return interfaceManagerCommonUtils.getInterfaceFromConfigDS(new InterfaceKey(interfaceName));
393 public void createVLANInterface(String interfaceName, String portName, BigInteger dpId, Integer vlanId,
394 String description, IfL2vlan.L2vlanMode l2vlanMode) throws InterfaceAlreadyExistsException {
395 createVLANInterface(interfaceName, portName, vlanId, description, l2vlanMode);
399 public void createVLANInterface(String interfaceName, String portName, Integer vlanId,
400 String description, IfL2vlan.L2vlanMode l2vlanMode) throws InterfaceAlreadyExistsException {
401 createVLANInterface(interfaceName, portName, vlanId, description, l2vlanMode, false);
405 public void createVLANInterface(String interfaceName, String portName, BigInteger dpId, Integer vlanId,
406 String description, IfL2vlan.L2vlanMode l2vlanMode, boolean isExternal)
407 throws InterfaceAlreadyExistsException {
408 createVLANInterface(interfaceName, portName, vlanId, description, l2vlanMode, isExternal);
412 public void createVLANInterface(String interfaceName, String portName, Integer vlanId,
413 String description, IfL2vlan.L2vlanMode l2vlanMode, boolean isExternal)
414 throws InterfaceAlreadyExistsException {
416 LOG.info("Create VLAN interface : {}", interfaceName);
417 Interface interfaceOptional = interfaceManagerCommonUtils
418 .getInterfaceFromConfigDS(new InterfaceKey(interfaceName));
419 if (interfaceOptional != null) {
420 LOG.debug("VLAN interface is already exist", interfaceOptional.getDescription());
421 throw new InterfaceAlreadyExistsException(interfaceOptional.getName());
423 IfL2vlanBuilder l2vlanBuilder = new IfL2vlanBuilder().setL2vlanMode(l2vlanMode);
424 if (vlanId != null && vlanId > 0) {
425 l2vlanBuilder.setVlanId(new VlanId(vlanId));
427 ParentRefs parentRefs = new ParentRefsBuilder().setParentInterface(portName).build();
428 InterfaceBuilder interfaceBuilder = new InterfaceBuilder().setEnabled(true).setName(interfaceName)
429 .setType(L2vlan.class).addAugmentation(IfL2vlan.class, l2vlanBuilder.build())
430 .addAugmentation(ParentRefs.class, parentRefs).setDescription(description);
432 interfaceBuilder.addAugmentation(IfExternal.class, new IfExternalBuilder().setExternal(true).build());
434 InstanceIdentifier<Interface> interfaceInstanceIdentifier = interfaceManagerCommonUtils
435 .getInterfaceIdentifier(new InterfaceKey(interfaceName));
436 // TODO Do something with the future...
437 txRunner.callWithNewWriteOnlyTransactionAndSubmit(
438 tx -> tx.put(LogicalDatastoreType.CONFIGURATION, interfaceInstanceIdentifier, interfaceBuilder.build(),
439 WriteTransaction.CREATE_MISSING_PARENTS));
442 private boolean isServiceBoundOnInterface(short servicePriority, String interfaceName,
443 Class<? extends ServiceModeBase> serviceMode) {
444 InstanceIdentifier<BoundServices> boundServicesIId = IfmUtil.buildBoundServicesIId(servicePriority,
445 interfaceName, serviceMode);
447 return SingleTransactionDataBroker
448 .syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION, boundServicesIId).isPresent();
449 } catch (ReadFailedException e) {
450 LOG.warn("Error while reading [{}]", boundServicesIId, e);
456 public boolean isServiceBoundOnInterfaceForIngress(short servicePriority, String interfaceName) {
457 return isServiceBoundOnInterface(servicePriority, interfaceName, ServiceModeIngress.class);
461 public boolean isServiceBoundOnInterfaceForEgress(short servicePriority, String interfaceName) {
462 return isServiceBoundOnInterface(servicePriority, interfaceName, ServiceModeEgress.class);
466 public void bindService(String interfaceName, Class<? extends ServiceModeBase> serviceMode,
467 BoundServices serviceInfo) {
468 bindService(interfaceName, serviceMode, serviceInfo, /* WriteTransaction */ null);
472 public void bindService(String interfaceName, Class<? extends ServiceModeBase> serviceMode,
473 BoundServices serviceInfo, WriteTransaction tx) {
474 WriteTransaction writeTransaction = tx != null ? tx : dataBroker.newWriteOnlyTransaction();
475 IfmUtil.bindService(writeTransaction, interfaceName, serviceInfo, serviceMode);
477 writeTransaction.submit();
482 public void unbindService(String interfaceName, Class<? extends ServiceModeBase> serviceMode,
483 BoundServices serviceInfo) {
484 IfmUtil.unbindService(txRunner, coordinator, interfaceName,
485 FlowBasedServicesUtils.buildServiceId(interfaceName, serviceInfo.getServicePriority(), serviceMode));
489 public BigInteger getDpnForInterface(Interface intrf) {
490 return getDpnForInterface(intrf.getName());
494 public BigInteger 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(BigInteger 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.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 InterfaceParentEntry parentEntry = InterfaceMetaUtils.getInterfaceParentEntryFromConfigDS(parentInterface,
545 if (parentEntry == null) {
546 LOG.debug("No parent entry found for {}", parentInterface);
547 return Collections.emptyList();
550 List<InterfaceChildEntry> childEntries = parentEntry.getInterfaceChildEntry();
551 if (childEntries == null || childEntries.isEmpty()) {
552 LOG.debug("No child entries found for parent {}", parentInterface);
553 return Collections.emptyList();
556 List<Interface> childInterfaces = new ArrayList<>();
557 for (InterfaceChildEntry childEntry : childEntries) {
558 String interfaceName = childEntry.getChildInterface();
559 Interface iface = interfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceName);
561 childInterfaces.add(iface);
563 LOG.debug("Child interface {} not found in config DS for parent interface {}", interfaceName,
568 LOG.trace("Found child interfaces {} for parent {}", childInterfaces, parentInterface);
569 return childInterfaces;
573 public boolean isExternalInterface(String interfaceName) {
574 return isExternalInterface(getInterfaceInfoFromConfigDataStore(interfaceName));
577 private boolean isExternalInterface(Interface iface) {
582 IfExternal ifExternal = iface.getAugmentation(IfExternal.class);
583 return ifExternal != null && Boolean.TRUE.equals(ifExternal.isExternal());
587 public String getPortNameForInterface(NodeConnectorId nodeConnectorId, String interfaceName) {
588 return InterfaceManagerCommonUtils.getPortNameForInterface(nodeConnectorId, interfaceName);
592 public String getPortNameForInterface(String dpnId, String interfaceName) {
593 return InterfaceManagerCommonUtils.getPortNameForInterface(dpnId, interfaceName);
597 public Map<String, OvsdbTerminationPointAugmentation> getTerminationPointCache() {
598 return new ConcurrentHashMap<>(this.ifaceToTpMap);
601 public void addTerminationPointForInterface(String interfaceName,
602 OvsdbTerminationPointAugmentation terminationPoint) {
603 LOG.debug("Adding TerminationPoint {} to cache for Interface {}", terminationPoint.getName(), interfaceName);
604 if (interfaceName != null && terminationPoint != null) {
605 ifaceToTpMap.put(interfaceName, terminationPoint);
609 public OvsdbTerminationPointAugmentation getTerminationPoint(String interfaceName) {
610 return ifaceToTpMap.get(interfaceName);
613 public void removeTerminationPointForInterface(String interfaceName) {
614 LOG.debug("Removing TerminationPoint from cache for Interface {}", interfaceName);
615 if (interfaceName != null) {
616 ifaceToTpMap.remove(interfaceName);
620 public void addNodeIidForInterface(String interfaceName, InstanceIdentifier<Node> nodeIid) {
621 if (interfaceName != null && nodeIid != null) {
622 ifaceToNodeIidMap.put(interfaceName, nodeIid);
626 public void removeNodeIidForInterface(String interfaceName) {
627 if (interfaceName != null) {
628 ifaceToNodeIidMap.remove(interfaceName);
632 public InstanceIdentifier<Node> getNodeIidForInterface(String interfaceName) {
633 if (interfaceName != null) {
634 return ifaceToNodeIidMap.get(interfaceName);
639 private OvsdbBridgeAugmentation getBridgeForInterface(String interfaceName,
640 InstanceIdentifier<Node> nodeInstanceId) {
641 InstanceIdentifier<Node> nodeIid = nodeInstanceId;
642 if (nodeIid == null) {
643 nodeIid = getNodeIidForInterface(interfaceName);
645 return getBridgeForNodeIid(nodeIid);
648 public String getDpidForInterface(String interfaceName) {
649 return getDpidForInterface(interfaceName, null);
652 public String getDpidForInterface(String interfaceName, InstanceIdentifier<Node> nodeInstanceId) {
653 OvsdbBridgeAugmentation bridge = getBridgeForInterface(interfaceName, nodeInstanceId);
654 if (bridge != null) {
655 BigInteger dpid = IfmUtil.getDpnId(bridge.getDatapathId());
656 if (dpid != null && dpid.longValue() != 0) {
657 return String.valueOf(dpid);
663 public void addBridgeForNodeIid(InstanceIdentifier<Node> nodeIid, OvsdbBridgeAugmentation bridge) {
664 if (nodeIid != null && bridge != null) {
665 nodeIidToBridgeMap.put(nodeIid, bridge);
669 public void removeBridgeForNodeIid(InstanceIdentifier<Node> nodeIid) {
670 if (nodeIid != null) {
671 nodeIidToBridgeMap.remove(nodeIid);
675 public OvsdbBridgeAugmentation getBridgeForNodeIid(InstanceIdentifier<Node> nodeIid) {
676 if (nodeIid != null) {
677 return nodeIidToBridgeMap.get(nodeIid);
683 public String getParentRefNameForInterface(String interfaceName) {
684 String parentRefName = null;
686 String dpnId = getDpidForInterface(interfaceName, null);
687 OvsdbTerminationPointAugmentation ovsdbTp = getTerminationPoint(interfaceName);
688 if (ovsdbTp != null) {
690 LOG.error("Got NULL dpnId when looking for TP with external ID {}", interfaceName);
693 parentRefName = getPortNameForInterface(dpnId, ovsdbTp.getName());
694 LOG.debug("Building parent ref for interface {}, using parentRefName {} acquired by external ID",
695 interfaceName, parentRefName);
697 LOG.debug("Skipping parent ref for interface {}, as there is no termination point that references "
698 + "this interface yet.", interfaceName);
701 return parentRefName;
705 public void updateInterfaceParentRef(String interfaceName, String parentInterface) {
706 // This should generally be called by EOS Owner for
707 // INTERFACE_CONFIG_ENTITY - runOnlyInLeaderNode()
708 updateInterfaceParentRef(interfaceName, parentInterface, true);
712 public void updateInterfaceParentRef(String interfaceName, String parentInterface,
713 boolean readInterfaceBeforeWrite) {
714 // This should generally be called by EOS Owner for
715 // INTERFACE_CONFIG_ENTITY - runOnlyInLeaderNode()
716 if (interfaceName == null) {
720 ParentRefUpdateWorker parentRefUpdateWorker = new ParentRefUpdateWorker(interfaceName, parentInterface,
721 readInterfaceBeforeWrite);
722 coordinator.enqueueJob(interfaceName, parentRefUpdateWorker, IfmConstants.JOB_MAX_RETRIES);
725 public class ParentRefUpdateWorker implements Callable<List<ListenableFuture<Void>>> {
726 String interfaceName;
727 String parentInterfaceName;
728 Boolean readInterfaceBeforeWrite;
730 public ParentRefUpdateWorker(String interfaceName, String parentInterfaceName,
731 boolean readInterfaceBeforeWrite) {
732 this.interfaceName = interfaceName;
733 this.parentInterfaceName = parentInterfaceName;
734 this.readInterfaceBeforeWrite = readInterfaceBeforeWrite;
738 public List<ListenableFuture<Void>> call() throws Exception {
739 if (readInterfaceBeforeWrite) {
740 Interface iface = interfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceName);
742 LOG.debug("Interface doesn't exist in config DS - no need to update parentRef, skipping");
746 return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(
747 tx -> IfmUtil.updateInterfaceParentRef(tx, interfaceName, parentInterfaceName)));
752 public OvsdbTerminationPointAugmentation getTerminationPointForInterface(String interfaceName) {
753 return getTerminationPoint(interfaceName);
757 public OvsdbBridgeAugmentation getOvsdbBridgeForInterface(String interfaceName) {
758 return getBridgeForInterface(interfaceName, null);
762 public OvsdbBridgeAugmentation getOvsdbBridgeForNodeIid(InstanceIdentifier<Node> nodeIid) {
763 return getBridgeForNodeIid(nodeIid);
768 * Get all termination points on a given DPN.
769 * This API uses read on Operational DS. If there are perf issues in cluster
770 * setup, we can consider caching later.
773 * Datapath Node Identifier
775 * @return If the data at the supplied path exists, returns a list of all termination point
778 public List<OvsdbTerminationPointAugmentation> getPortsOnBridge(BigInteger dpnId) {
779 List<OvsdbTerminationPointAugmentation> ports = new ArrayList<>();
780 List<TerminationPoint> portList = IfmUtil.getTerminationPointsOnBridge(dataBroker, dpnId);
781 for (TerminationPoint ovsPort : portList) {
782 if (ovsPort.getAugmentation(OvsdbTerminationPointAugmentation.class) != null) {
783 ports.add(ovsPort.getAugmentation(OvsdbTerminationPointAugmentation.class));
786 LOG.debug("Found {} ports on bridge {}", ports.size(), dpnId);
791 * Get all termination points of type tunnel on a given DPN.
794 * Datapath Node Identifier
796 * @return If the data at the supplied path exists, returns a list of all termination point
797 * Augmentations of type tunnel
800 public List<OvsdbTerminationPointAugmentation> getTunnelPortsOnBridge(BigInteger dpnId) {
801 List<OvsdbTerminationPointAugmentation> tunnelPorts = new ArrayList<>();
802 List<TerminationPoint> portList = IfmUtil.getTerminationPointsOnBridge(dataBroker, dpnId);
803 for (TerminationPoint ovsPort : portList) {
804 OvsdbTerminationPointAugmentation portAug =
805 ovsPort.getAugmentation(OvsdbTerminationPointAugmentation.class);
806 if (portAug != null && SouthboundUtils.isInterfaceTypeTunnel(portAug.getInterfaceType())) {
807 tunnelPorts.add(portAug);
811 LOG.debug("Found {} tunnel ports on bridge {}", tunnelPorts.size(), dpnId);
816 * Get all termination points by type on a given DPN.
819 * Datapath Node Identifier
821 * @return If the data at the supplied path exists, returns a Map where key is interfaceType
822 * and value is list of termination points of given type
825 public Map<Class<? extends InterfaceTypeBase>, List<OvsdbTerminationPointAugmentation>>
826 getPortsOnBridgeByType(BigInteger dpnId) {
828 Map<Class<? extends InterfaceTypeBase>, List<OvsdbTerminationPointAugmentation>> portMap;
829 portMap = new ConcurrentHashMap<>();
830 List<TerminationPoint> ovsPorts = IfmUtil.getTerminationPointsOnBridge(dataBroker, dpnId);
831 if (ovsPorts != null) {
832 for (TerminationPoint ovsPort : ovsPorts) {
833 OvsdbTerminationPointAugmentation portAug =
834 ovsPort.getAugmentation(OvsdbTerminationPointAugmentation.class);
835 if (portAug != null && portAug.getInterfaceType() != null) {
836 portMap.computeIfAbsent(portAug.getInterfaceType(), k -> new ArrayList<>()).add(portAug);
844 public long getLogicalTunnelSelectGroupId(int lportTag) {
845 return IfmUtil.getLogicalTunnelSelectGroupId(lportTag);