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 static org.opendaylight.controller.md.sal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
11 import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.CONFIGURATION;
13 import com.google.common.util.concurrent.ListenableFuture;
14 import java.math.BigInteger;
15 import java.util.ArrayList;
16 import java.util.Collections;
17 import java.util.List;
19 import java.util.concurrent.Callable;
20 import java.util.concurrent.ConcurrentHashMap;
21 import java.util.concurrent.ExecutionException;
22 import java.util.concurrent.Future;
23 import javax.annotation.PostConstruct;
24 import javax.annotation.PreDestroy;
25 import javax.inject.Inject;
26 import javax.inject.Singleton;
27 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
28 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
29 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
30 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
31 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
32 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
33 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
34 import org.opendaylight.genius.interfacemanager.commons.InterfaceManagerCommonUtils;
35 import org.opendaylight.genius.interfacemanager.commons.InterfaceMetaUtils;
36 import org.opendaylight.genius.interfacemanager.exceptions.InterfaceAlreadyExistsException;
37 import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo;
38 import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo.InterfaceAdminState;
39 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
40 import org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.SouthboundUtils;
41 import org.opendaylight.genius.interfacemanager.rpcservice.InterfaceManagerRpcService;
42 import org.opendaylight.genius.interfacemanager.servicebindings.flowbased.utilities.FlowBasedServicesUtils;
43 import org.opendaylight.genius.interfacemanager.statusanddiag.InterfaceStatusMonitor;
44 import org.opendaylight.genius.mdsalutil.ActionInfo;
45 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
46 import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
47 import org.opendaylight.mdsal.eos.binding.api.Entity;
48 import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipCandidateRegistration;
49 import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipService;
50 import org.opendaylight.mdsal.eos.common.api.CandidateAlreadyRegisteredException;
51 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan;
52 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel;
53 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
54 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
55 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
56 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
57 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus;
58 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus;
59 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInput;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInputBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info.InterfaceParentEntry;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info._interface.parent.entry.InterfaceChildEntry;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfExternal;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfExternalBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlanBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefs;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefsBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEndpointIpForDpnInput;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEndpointIpForDpnInputBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEndpointIpForDpnOutput;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceInput;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceInputBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceOutput;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeBase;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeEgress;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeIngress;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServices;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeBase;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
89 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
90 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
91 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
92 import org.opendaylight.yangtools.yang.common.RpcResult;
93 import org.slf4j.Logger;
94 import org.slf4j.LoggerFactory;
97 public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
98 private static final Logger LOG = LoggerFactory.getLogger(InterfacemgrProvider.class);
100 private final DataBroker dataBroker;
101 private final ManagedNewTransactionRunner txRunner;
102 private final IdManagerService idManager;
103 private final InterfaceManagerRpcService interfaceManagerRpcService;
104 private final EntityOwnershipService entityOwnershipService;
105 private final JobCoordinator coordinator;
106 private final InterfaceManagerCommonUtils interfaceManagerCommonUtils;
107 private final InterfaceMetaUtils interfaceMetaUtils;
108 private final InterfaceStatusMonitor interfaceStatusMonitor = new InterfaceStatusMonitor();
109 private Map<String, OvsdbTerminationPointAugmentation> ifaceToTpMap;
110 private Map<String, InstanceIdentifier<Node>> ifaceToNodeIidMap;
111 private Map<InstanceIdentifier<Node>, OvsdbBridgeAugmentation> nodeIidToBridgeMap;
112 private EntityOwnershipCandidateRegistration configEntityCandidate;
113 private EntityOwnershipCandidateRegistration bindingEntityCandidate;
116 public InterfacemgrProvider(final DataBroker dataBroker, final EntityOwnershipService entityOwnershipService,
117 final IdManagerService idManager, final InterfaceManagerRpcService interfaceManagerRpcService,
118 final JobCoordinator coordinator, final InterfaceManagerCommonUtils interfaceManagerCommonUtils,
119 final InterfaceMetaUtils interfaceMetaUtils) {
120 this.dataBroker = dataBroker;
121 this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
122 this.entityOwnershipService = entityOwnershipService;
123 this.idManager = idManager;
124 this.interfaceManagerRpcService = interfaceManagerRpcService;
125 this.coordinator = coordinator;
126 this.interfaceManagerCommonUtils = interfaceManagerCommonUtils;
127 this.interfaceMetaUtils = interfaceMetaUtils;
131 @SuppressWarnings("checkstyle:IllegalCatch")
132 public void start() {
134 interfaceStatusMonitor.registerMbean();
138 configEntityCandidate = entityOwnershipService.registerCandidate(
139 new Entity(IfmConstants.INTERFACE_CONFIG_ENTITY, IfmConstants.INTERFACE_CONFIG_ENTITY));
140 bindingEntityCandidate = entityOwnershipService.registerCandidate(
141 new Entity(IfmConstants.INTERFACE_SERVICE_BINDING_ENTITY,
142 IfmConstants.INTERFACE_SERVICE_BINDING_ENTITY));
143 } catch (CandidateAlreadyRegisteredException e) {
144 LOG.error("Failed to register entity {} with EntityOwnershipService", e.getEntity());
147 this.ifaceToTpMap = new ConcurrentHashMap<>();
148 this.ifaceToNodeIidMap = new ConcurrentHashMap<>();
149 this.nodeIidToBridgeMap = new ConcurrentHashMap<>();
151 interfaceStatusMonitor.reportStatus("OPERATIONAL");
152 } catch (Exception e) {
153 interfaceStatusMonitor.reportStatus("ERROR");
156 LOG.info("InterfacemgrProvider Started");
161 public void close() throws Exception {
162 interfaceStatusMonitor.unregisterMbean();
164 if (configEntityCandidate != null) {
165 configEntityCandidate.close();
168 if (bindingEntityCandidate != null) {
169 bindingEntityCandidate.close();
172 LOG.info("InterfacemgrProvider Closed");
175 public EntityOwnershipService getEntityOwnershipService() {
176 return entityOwnershipService;
179 public DataBroker getDataBroker() {
180 return this.dataBroker;
183 private void createIdPool() {
184 CreateIdPoolInput createPool = new CreateIdPoolInputBuilder().setPoolName(IfmConstants.IFM_IDPOOL_NAME)
185 .setLow(IfmConstants.IFM_ID_POOL_START).setHigh(IfmConstants.IFM_ID_POOL_END).build();
186 // TODO: Error handling
187 Future<RpcResult<Void>> result = idManager.createIdPool(createPool);
189 if (result != null && result.get().isSuccessful()) {
190 LOG.debug("Created IdPool for InterfaceMgr");
192 } catch (InterruptedException | ExecutionException e) {
193 LOG.error("Failed to create idPool for InterfaceMgr", e);
198 public Long getPortForInterface(String ifName) {
199 GetPortFromInterfaceInput input = new GetPortFromInterfaceInputBuilder().setIntfName(ifName).build();
200 Future<RpcResult<GetPortFromInterfaceOutput>> output = interfaceManagerRpcService.getPortFromInterface(input);
202 RpcResult<GetPortFromInterfaceOutput> port = output.get();
203 if (port.isSuccessful()) {
204 return port.getResult().getPortno();
206 } catch (NullPointerException | InterruptedException | ExecutionException e) {
207 LOG.warn("Exception when getting port for interface", e);
213 public Long getPortForInterface(Interface intf) {
214 GetPortFromInterfaceInput input = new GetPortFromInterfaceInputBuilder().setIntfName(intf.getName()).build();
215 Future<RpcResult<GetPortFromInterfaceOutput>> output = interfaceManagerRpcService.getPortFromInterface(input);
217 RpcResult<GetPortFromInterfaceOutput> port = output.get();
218 if (port.isSuccessful()) {
219 return port.getResult().getPortno();
221 } catch (NullPointerException | InterruptedException | ExecutionException e) {
222 LOG.warn("Exception when getting port for interface", e);
228 public InterfaceInfo getInterfaceInfo(String interfaceName) {
230 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
231 .ietf.interfaces.rev140508.interfaces.state.Interface ifState = interfaceManagerCommonUtils
232 .getInterfaceState(interfaceName);
234 if (ifState == null) {
235 LOG.debug("Interface {} is not present", interfaceName);
239 Interface intf = interfaceManagerCommonUtils.getInterfaceFromConfigDS(new InterfaceKey(interfaceName));
241 LOG.error("Interface {} doesn't exist in config datastore", interfaceName);
245 NodeConnectorId ncId = FlowBasedServicesUtils.getNodeConnectorIdFromInterface(intf.getName(),
246 interfaceManagerCommonUtils);
247 InterfaceInfo.InterfaceType interfaceType = IfmUtil.getInterfaceType(intf);
248 InterfaceInfo interfaceInfo = new InterfaceInfo(interfaceName);
249 BigInteger dpId = org.opendaylight.genius.interfacemanager.globals.IfmConstants.INVALID_DPID;
250 Integer portNo = org.opendaylight.genius.interfacemanager.globals.IfmConstants.INVALID_PORT_NO;
252 dpId = IfmUtil.getDpnFromNodeConnectorId(ncId);
253 portNo = Integer.parseInt(IfmUtil.getPortNoFromNodeConnectorId(ncId));
255 if (interfaceType == InterfaceInfo.InterfaceType.VLAN_INTERFACE) {
256 interfaceInfo = IfmUtil.getVlanInterfaceInfo(intf, dpId);
257 } else if (interfaceType == InterfaceInfo.InterfaceType.UNKNOWN_INTERFACE) {
258 LOG.error("Type of Interface {} is unknown", interfaceName);
261 InterfaceInfo.InterfaceOpState opState;
262 if (ifState.getOperStatus() == OperStatus.Up) {
263 opState = InterfaceInfo.InterfaceOpState.UP;
264 } else if (ifState.getOperStatus() == OperStatus.Down) {
265 opState = InterfaceInfo.InterfaceOpState.DOWN;
267 opState = InterfaceInfo.InterfaceOpState.UNKNOWN;
269 interfaceInfo.setDpId(dpId);
270 interfaceInfo.setPortNo(portNo);
271 interfaceInfo.setAdminState(intf.isEnabled() ? InterfaceAdminState.ENABLED : InterfaceAdminState.DISABLED);
272 interfaceInfo.setInterfaceName(interfaceName);
273 Integer lportTag = ifState.getIfIndex();
274 interfaceInfo.setInterfaceTag(lportTag);
275 interfaceInfo.setInterfaceType(interfaceType);
276 interfaceInfo.setGroupId(IfmUtil.getGroupId(lportTag, interfaceType));
277 interfaceInfo.setOpState(opState);
278 PhysAddress phyAddress = ifState.getPhysAddress();
279 if (phyAddress != null) {
280 interfaceInfo.setMacAddress(ifState.getPhysAddress().getValue());
283 return interfaceInfo;
288 public InterfaceInfo getInterfaceInfoFromOperationalDataStore(String interfaceName,
289 InterfaceInfo.InterfaceType interfaceType) {
290 InterfaceInfo interfaceInfo = new InterfaceInfo(interfaceName);
291 org.opendaylight.yang.gen.v1.urn
292 .ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState =
293 interfaceManagerCommonUtils.getInterfaceState(interfaceName);
294 if (ifState == null) {
295 LOG.debug("Interface {} is not present", interfaceName);
298 NodeConnectorId ncId = IfmUtil.getNodeConnectorIdFromInterface(ifState);
300 interfaceInfo.setDpId(IfmUtil.getDpnFromNodeConnectorId(ncId));
301 interfaceInfo.setPortNo(Integer.parseInt(IfmUtil.getPortNoFromNodeConnectorId(ncId)));
303 InterfaceInfo.InterfaceOpState opState;
304 if (ifState.getOperStatus() == OperStatus.Up) {
305 opState = InterfaceInfo.InterfaceOpState.UP;
306 } else if (ifState.getOperStatus() == OperStatus.Down) {
307 opState = InterfaceInfo.InterfaceOpState.DOWN;
309 opState = InterfaceInfo.InterfaceOpState.UNKNOWN;
311 interfaceInfo.setAdminState(ifState.getAdminStatus() == AdminStatus.Up ? InterfaceAdminState.ENABLED
312 : InterfaceAdminState.DISABLED);
313 interfaceInfo.setInterfaceName(interfaceName);
314 Integer lportTag = ifState.getIfIndex();
315 interfaceInfo.setInterfaceTag(lportTag);
316 interfaceInfo.setInterfaceType(interfaceType);
317 interfaceInfo.setGroupId(IfmUtil.getGroupId(lportTag, interfaceType));
318 interfaceInfo.setOpState(opState);
319 PhysAddress phyAddress = ifState.getPhysAddress();
320 if (phyAddress != null) {
321 interfaceInfo.setMacAddress(ifState.getPhysAddress().getValue());
323 return interfaceInfo;
327 public InterfaceInfo getInterfaceInfoFromOperationalDataStore(String interfaceName) {
328 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
329 .ietf.interfaces.rev140508.interfaces.state.Interface ifState = interfaceManagerCommonUtils
330 .getInterfaceState(interfaceName);
331 if (ifState == null) {
332 LOG.debug("Interface {} is not present", interfaceName);
336 return populateInterfaceInfo(interfaceName, ifState);
339 public InterfaceInfo populateInterfaceInfo(String interfaceName,
340 org.opendaylight.yang.gen.v1.urn
341 .ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState) {
342 InterfaceInfo interfaceInfo = new InterfaceInfo(interfaceName);
343 NodeConnectorId ncId = IfmUtil.getNodeConnectorIdFromInterface(ifState);
345 if (Tunnel.class.equals(ifState.getType())) {
346 interfaceInfo.setPortName(interfaceName);
348 Interface iface = interfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceName);
350 ParentRefs parentRefs = iface.getAugmentation(ParentRefs.class);
351 interfaceInfo.setPortName(parentRefs.getParentInterface());
354 interfaceInfo.setDpId(IfmUtil.getDpnFromNodeConnectorId(ncId));
355 interfaceInfo.setPortNo(Integer.parseInt(IfmUtil.getPortNoFromNodeConnectorId(ncId)));
357 InterfaceInfo.InterfaceOpState opState;
358 if (ifState.getOperStatus() == OperStatus.Up) {
359 opState = InterfaceInfo.InterfaceOpState.UP;
360 } else if (ifState.getOperStatus() == OperStatus.Down) {
361 opState = InterfaceInfo.InterfaceOpState.DOWN;
363 opState = InterfaceInfo.InterfaceOpState.UNKNOWN;
365 interfaceInfo.setAdminState(ifState.getAdminStatus() == AdminStatus.Up ? InterfaceAdminState.ENABLED
366 : InterfaceAdminState.DISABLED);
367 interfaceInfo.setInterfaceName(interfaceName);
368 Integer lportTag = ifState.getIfIndex();
369 if (lportTag != null) {
370 interfaceInfo.setInterfaceTag(lportTag);
372 interfaceInfo.setOpState(opState);
373 PhysAddress phyAddress = ifState.getPhysAddress();
374 if (phyAddress != null) {
375 interfaceInfo.setMacAddress(ifState.getPhysAddress().getValue());
377 return interfaceInfo;
381 public InterfaceInfo getInterfaceInfoFromOperationalDSCache(String interfaceName) {
382 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
383 .ietf.interfaces.rev140508.interfaces.state.Interface ifState = interfaceManagerCommonUtils
384 .getInterfaceStateFromCache(interfaceName);
385 if (ifState == null) {
386 LOG.warn("Interface {} is not present", interfaceName);
389 return populateInterfaceInfo(interfaceName, ifState);
393 public Interface getInterfaceInfoFromConfigDataStore(String interfaceName) {
394 return interfaceManagerCommonUtils.getInterfaceFromConfigDS(new InterfaceKey(interfaceName));
398 public void createVLANInterface(String interfaceName, String portName, BigInteger dpId, Integer vlanId,
399 String description, IfL2vlan.L2vlanMode l2vlanMode) throws InterfaceAlreadyExistsException {
400 createVLANInterface(interfaceName, portName, vlanId, description, l2vlanMode);
404 public void createVLANInterface(String interfaceName, String portName, Integer vlanId,
405 String description, IfL2vlan.L2vlanMode l2vlanMode) throws InterfaceAlreadyExistsException {
406 createVLANInterface(interfaceName, portName, vlanId, description, l2vlanMode, false);
410 public void createVLANInterface(String interfaceName, String portName, BigInteger dpId, Integer vlanId,
411 String description, IfL2vlan.L2vlanMode l2vlanMode, boolean isExternal)
412 throws InterfaceAlreadyExistsException {
413 createVLANInterface(interfaceName, portName, vlanId, description, l2vlanMode, isExternal);
417 public void createVLANInterface(String interfaceName, String portName, Integer vlanId,
418 String description, IfL2vlan.L2vlanMode l2vlanMode, boolean isExternal)
419 throws InterfaceAlreadyExistsException {
421 LOG.info("Create VLAN interface : {}", interfaceName);
422 Interface interfaceOptional = interfaceManagerCommonUtils
423 .getInterfaceFromConfigDS(new InterfaceKey(interfaceName));
424 if (interfaceOptional != null) {
425 LOG.debug("VLAN interface is already exist", interfaceOptional.getDescription());
426 throw new InterfaceAlreadyExistsException(interfaceOptional.getName());
428 IfL2vlanBuilder l2vlanBuilder = new IfL2vlanBuilder().setL2vlanMode(l2vlanMode);
429 if (vlanId != null && vlanId > 0) {
430 l2vlanBuilder.setVlanId(new VlanId(vlanId));
432 ParentRefs parentRefs = new ParentRefsBuilder().setParentInterface(portName).build();
433 InterfaceBuilder interfaceBuilder = new InterfaceBuilder().setEnabled(true).setName(interfaceName)
434 .setType(L2vlan.class).addAugmentation(IfL2vlan.class, l2vlanBuilder.build())
435 .addAugmentation(ParentRefs.class, parentRefs).setDescription(description);
437 interfaceBuilder.addAugmentation(IfExternal.class, new IfExternalBuilder().setExternal(true).build());
439 InstanceIdentifier<Interface> interfaceIId = interfaceManagerCommonUtils
440 .getInterfaceIdentifier(new InterfaceKey(interfaceName));
441 ListenableFutures.addErrorLogging(
442 txRunner.callWithNewWriteOnlyTransactionAndSubmit(
443 tx -> tx.put(CONFIGURATION, interfaceIId, interfaceBuilder.build(), CREATE_MISSING_PARENTS)),
444 LOG, "Failed to (async) write {}", interfaceIId);
447 private boolean isServiceBoundOnInterface(short servicePriority, String interfaceName,
448 Class<? extends ServiceModeBase> serviceMode) {
449 InstanceIdentifier<BoundServices> boundServicesIId = IfmUtil.buildBoundServicesIId(servicePriority,
450 interfaceName, serviceMode);
452 return SingleTransactionDataBroker
453 .syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION, boundServicesIId).isPresent();
454 } catch (ReadFailedException e) {
455 LOG.warn("Error while reading [{}]", boundServicesIId, e);
461 public boolean isServiceBoundOnInterfaceForIngress(short servicePriority, String interfaceName) {
462 return isServiceBoundOnInterface(servicePriority, interfaceName, ServiceModeIngress.class);
466 public boolean isServiceBoundOnInterfaceForEgress(short servicePriority, String interfaceName) {
467 return isServiceBoundOnInterface(servicePriority, interfaceName, ServiceModeEgress.class);
471 public void bindService(String interfaceName, Class<? extends ServiceModeBase> serviceMode,
472 BoundServices serviceInfo) {
473 bindService(interfaceName, serviceMode, serviceInfo, /* WriteTransaction */ null);
477 public void bindService(String interfaceName, Class<? extends ServiceModeBase> serviceMode,
478 BoundServices serviceInfo, WriteTransaction tx) {
479 WriteTransaction writeTransaction = tx != null ? tx : dataBroker.newWriteOnlyTransaction();
480 IfmUtil.bindService(writeTransaction, interfaceName, serviceInfo, serviceMode);
482 writeTransaction.submit();
487 public void unbindService(String interfaceName, Class<? extends ServiceModeBase> serviceMode,
488 BoundServices serviceInfo) {
489 IfmUtil.unbindService(txRunner, coordinator, interfaceName,
490 FlowBasedServicesUtils.buildServiceId(interfaceName, serviceInfo.getServicePriority(), serviceMode));
494 public BigInteger getDpnForInterface(Interface intrf) {
495 return getDpnForInterface(intrf.getName());
499 public BigInteger getDpnForInterface(String ifName) {
500 GetDpidFromInterfaceInput input = new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
501 Future<RpcResult<GetDpidFromInterfaceOutput>> output = interfaceManagerRpcService.getDpidFromInterface(input);
503 RpcResult<GetDpidFromInterfaceOutput> dpn = output.get();
504 if (dpn.isSuccessful()) {
505 return dpn.getResult().getDpid();
507 } catch (NullPointerException | InterruptedException | ExecutionException e) {
508 LOG.warn("Exception when getting port for interface", e);
514 public String getEndpointIpForDpn(BigInteger dpnId) {
515 GetEndpointIpForDpnInput input = new GetEndpointIpForDpnInputBuilder().setDpid(dpnId).build();
516 Future<RpcResult<GetEndpointIpForDpnOutput>> output = interfaceManagerRpcService.getEndpointIpForDpn(input);
518 RpcResult<GetEndpointIpForDpnOutput> ipForDpnOutputRpcResult = output.get();
519 if (ipForDpnOutputRpcResult.isSuccessful()) {
520 List<IpAddress> localIps = ipForDpnOutputRpcResult.getResult().getLocalIps();
521 if (!localIps.isEmpty()) {
522 return localIps.get(0).getIpv4Address().getValue();
525 } catch (NullPointerException | InterruptedException | ExecutionException e) {
526 LOG.warn("Exception when getting port for interface", e);
532 public List<ActionInfo> getInterfaceEgressActions(String ifName) {
533 return IfmUtil.getEgressActionInfosForInterface(ifName, 0, interfaceManagerCommonUtils, false);
537 public List<Interface> getVlanInterfaces() {
538 return interfaceManagerCommonUtils.getAllVlanInterfacesFromCache();
542 public List<Interface> getVxlanInterfaces() {
543 return interfaceManagerCommonUtils.getAllTunnelInterfacesFromCache();
547 public List<Interface> getChildInterfaces(String parentInterface) {
548 InterfaceParentEntry parentEntry = interfaceMetaUtils.getInterfaceParentEntryFromConfigDS(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(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));
581 private boolean isExternalInterface(Interface iface) {
586 IfExternal ifExternal = iface.getAugmentation(IfExternal.class);
587 return ifExternal != null && Boolean.TRUE.equals(ifExternal.isExternal());
591 public String getPortNameForInterface(NodeConnectorId nodeConnectorId, String interfaceName) {
592 return InterfaceManagerCommonUtils.getPortNameForInterface(nodeConnectorId, interfaceName);
596 public String getPortNameForInterface(String dpnId, String interfaceName) {
597 return InterfaceManagerCommonUtils.getPortNameForInterface(dpnId, interfaceName);
601 public Map<String, OvsdbTerminationPointAugmentation> getTerminationPointCache() {
602 return new ConcurrentHashMap<>(this.ifaceToTpMap);
605 public void addTerminationPointForInterface(String interfaceName,
606 OvsdbTerminationPointAugmentation terminationPoint) {
607 if (interfaceName != null && terminationPoint != null) {
608 LOG.debug("Adding TerminationPoint {} to cache for Interface {}", terminationPoint.getName(),
610 ifaceToTpMap.put(interfaceName, terminationPoint);
614 public OvsdbTerminationPointAugmentation getTerminationPoint(String interfaceName) {
615 return ifaceToTpMap.get(interfaceName);
618 public void removeTerminationPointForInterface(String interfaceName) {
619 LOG.debug("Removing TerminationPoint from cache for Interface {}", interfaceName);
620 if (interfaceName != null) {
621 ifaceToTpMap.remove(interfaceName);
625 public void addNodeIidForInterface(String interfaceName, InstanceIdentifier<Node> nodeIid) {
626 if (interfaceName != null && nodeIid != null) {
627 ifaceToNodeIidMap.put(interfaceName, nodeIid);
631 public void removeNodeIidForInterface(String interfaceName) {
632 if (interfaceName != null) {
633 ifaceToNodeIidMap.remove(interfaceName);
637 public InstanceIdentifier<Node> getNodeIidForInterface(String interfaceName) {
638 if (interfaceName != null) {
639 return ifaceToNodeIidMap.get(interfaceName);
644 private OvsdbBridgeAugmentation getBridgeForInterface(String interfaceName,
645 InstanceIdentifier<Node> nodeInstanceId) {
646 InstanceIdentifier<Node> nodeIid = nodeInstanceId;
647 if (nodeIid == null) {
648 nodeIid = getNodeIidForInterface(interfaceName);
650 return getBridgeForNodeIid(nodeIid);
653 public String getDpidForInterface(String interfaceName) {
654 return getDpidForInterface(interfaceName, null);
657 public String getDpidForInterface(String interfaceName, InstanceIdentifier<Node> nodeInstanceId) {
658 OvsdbBridgeAugmentation bridge = getBridgeForInterface(interfaceName, nodeInstanceId);
659 if (bridge != null) {
660 BigInteger dpid = IfmUtil.getDpnId(bridge.getDatapathId());
661 if (dpid != null && dpid.longValue() != 0) {
662 return String.valueOf(dpid);
668 public void addBridgeForNodeIid(InstanceIdentifier<Node> nodeIid, OvsdbBridgeAugmentation bridge) {
669 if (nodeIid != null && bridge != null) {
670 nodeIidToBridgeMap.put(nodeIid, bridge);
674 public void removeBridgeForNodeIid(InstanceIdentifier<Node> nodeIid) {
675 if (nodeIid != null) {
676 nodeIidToBridgeMap.remove(nodeIid);
680 public OvsdbBridgeAugmentation getBridgeForNodeIid(InstanceIdentifier<Node> nodeIid) {
681 if (nodeIid != null) {
682 return nodeIidToBridgeMap.get(nodeIid);
688 public String getParentRefNameForInterface(String interfaceName) {
689 String parentRefName = null;
691 String dpnId = getDpidForInterface(interfaceName, null);
692 OvsdbTerminationPointAugmentation ovsdbTp = getTerminationPoint(interfaceName);
693 if (ovsdbTp != null) {
695 LOG.error("Got NULL dpnId when looking for TP with external ID {}", interfaceName);
698 parentRefName = getPortNameForInterface(dpnId, ovsdbTp.getName());
699 LOG.debug("Building parent ref for interface {}, using parentRefName {} acquired by external ID",
700 interfaceName, parentRefName);
702 LOG.debug("Skipping parent ref for interface {}, as there is no termination point that references "
703 + "this interface yet.", interfaceName);
706 return parentRefName;
710 public void updateInterfaceParentRef(String interfaceName, String parentInterface) {
711 // This should generally be called by EOS Owner for
712 // INTERFACE_CONFIG_ENTITY - runOnlyInLeaderNode()
713 updateInterfaceParentRef(interfaceName, parentInterface, true);
717 public void updateInterfaceParentRef(String interfaceName, String parentInterface,
718 boolean readInterfaceBeforeWrite) {
719 // This should generally be called by EOS Owner for
720 // INTERFACE_CONFIG_ENTITY - runOnlyInLeaderNode()
721 if (interfaceName == null) {
725 ParentRefUpdateWorker parentRefUpdateWorker = new ParentRefUpdateWorker(interfaceName, parentInterface,
726 readInterfaceBeforeWrite);
727 coordinator.enqueueJob(interfaceName, parentRefUpdateWorker, IfmConstants.JOB_MAX_RETRIES);
730 public class ParentRefUpdateWorker implements Callable<List<ListenableFuture<Void>>> {
731 String interfaceName;
732 String parentInterfaceName;
733 Boolean readInterfaceBeforeWrite;
735 public ParentRefUpdateWorker(String interfaceName, String parentInterfaceName,
736 boolean readInterfaceBeforeWrite) {
737 this.interfaceName = interfaceName;
738 this.parentInterfaceName = parentInterfaceName;
739 this.readInterfaceBeforeWrite = readInterfaceBeforeWrite;
743 public List<ListenableFuture<Void>> call() throws Exception {
744 if (readInterfaceBeforeWrite) {
745 Interface iface = interfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceName);
747 LOG.debug("Interface doesn't exist in config DS - no need to update parentRef, skipping");
751 return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(
752 tx -> IfmUtil.updateInterfaceParentRef(tx, interfaceName, parentInterfaceName)));
757 public OvsdbTerminationPointAugmentation getTerminationPointForInterface(String interfaceName) {
758 return getTerminationPoint(interfaceName);
762 public OvsdbBridgeAugmentation getOvsdbBridgeForInterface(String interfaceName) {
763 return getBridgeForInterface(interfaceName, null);
767 public OvsdbBridgeAugmentation getOvsdbBridgeForNodeIid(InstanceIdentifier<Node> nodeIid) {
768 return getBridgeForNodeIid(nodeIid);
773 * Get all termination points on a given DPN.
774 * This API uses read on Operational DS. If there are perf issues in cluster
775 * setup, we can consider caching later.
778 * Datapath Node Identifier
780 * @return If the data at the supplied path exists, returns a list of all termination point
783 public List<OvsdbTerminationPointAugmentation> getPortsOnBridge(BigInteger dpnId) {
784 List<OvsdbTerminationPointAugmentation> ports = new ArrayList<>();
785 List<TerminationPoint> portList = interfaceMetaUtils.getTerminationPointsOnBridge(dpnId);
786 for (TerminationPoint ovsPort : portList) {
787 if (ovsPort.getAugmentation(OvsdbTerminationPointAugmentation.class) != null) {
788 ports.add(ovsPort.getAugmentation(OvsdbTerminationPointAugmentation.class));
791 LOG.debug("Found {} ports on bridge {}", ports.size(), dpnId);
796 * Get all termination points of type tunnel on a given DPN.
799 * Datapath Node Identifier
801 * @return If the data at the supplied path exists, returns a list of all termination point
802 * Augmentations of type tunnel
805 public List<OvsdbTerminationPointAugmentation> getTunnelPortsOnBridge(BigInteger dpnId) {
806 List<OvsdbTerminationPointAugmentation> tunnelPorts = new ArrayList<>();
807 List<TerminationPoint> portList = interfaceMetaUtils.getTerminationPointsOnBridge(dpnId);
808 for (TerminationPoint ovsPort : portList) {
809 OvsdbTerminationPointAugmentation portAug =
810 ovsPort.getAugmentation(OvsdbTerminationPointAugmentation.class);
811 if (portAug != null && SouthboundUtils.isInterfaceTypeTunnel(portAug.getInterfaceType())) {
812 tunnelPorts.add(portAug);
816 LOG.debug("Found {} tunnel ports on bridge {}", tunnelPorts.size(), dpnId);
821 * Get all termination points by type on a given DPN.
824 * Datapath Node Identifier
826 * @return If the data at the supplied path exists, returns a Map where key is interfaceType
827 * and value is list of termination points of given type
830 public Map<Class<? extends InterfaceTypeBase>, List<OvsdbTerminationPointAugmentation>>
831 getPortsOnBridgeByType(BigInteger dpnId) {
833 Map<Class<? extends InterfaceTypeBase>, List<OvsdbTerminationPointAugmentation>> portMap;
834 portMap = new ConcurrentHashMap<>();
835 List<TerminationPoint> ovsPorts = interfaceMetaUtils.getTerminationPointsOnBridge(dpnId);
836 if (ovsPorts != null) {
837 for (TerminationPoint ovsPort : ovsPorts) {
838 OvsdbTerminationPointAugmentation portAug =
839 ovsPort.getAugmentation(OvsdbTerminationPointAugmentation.class);
840 if (portAug != null && portAug.getInterfaceType() != null) {
841 portMap.computeIfAbsent(portAug.getInterfaceType(), k -> new ArrayList<>()).add(portAug);
849 public long getLogicalTunnelSelectGroupId(int lportTag) {
850 return IfmUtil.getLogicalTunnelSelectGroupId(lportTag);