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.clustering.EntityOwnershipService;
27 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
28 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
29 import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
30 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
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.IfmClusterUtils;
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.interfacemanager.statusanddiag.InterfaceStatusMonitor;
43 import org.opendaylight.genius.mdsalutil.ActionInfo;
44 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel;
46 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
48 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
49 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
50 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus;
51 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus;
52 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInput;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInputBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info.InterfaceParentEntry;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info._interface.parent.entry.InterfaceChildEntry;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfExternal;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfExternalBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlanBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefs;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefsBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEndpointIpForDpnInput;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEndpointIpForDpnInputBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEndpointIpForDpnOutput;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceInput;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceInputBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceOutput;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeBase;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeEgress;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeIngress;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServices;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeBase;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
82 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
83 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
84 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
85 import org.opendaylight.yangtools.yang.common.RpcResult;
86 import org.slf4j.Logger;
87 import org.slf4j.LoggerFactory;
90 public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
91 private static final Logger LOG = LoggerFactory.getLogger(InterfacemgrProvider.class);
92 private static final InterfaceStatusMonitor INTERFACE_STATUS_MONITOR = InterfaceStatusMonitor.getInstance();
93 private final DataBroker dataBroker;
94 private final IdManagerService idManager;
95 private final InterfaceManagerRpcService interfaceManagerRpcService;
96 private final EntityOwnershipService entityOwnershipService;
97 private Map<String, OvsdbTerminationPointAugmentation> ifaceToTpMap;
98 private Map<String, InstanceIdentifier<Node>> ifaceToNodeIidMap;
99 private Map<InstanceIdentifier<Node>, OvsdbBridgeAugmentation> nodeIidToBridgeMap;
102 public InterfacemgrProvider(final DataBroker dataBroker, final EntityOwnershipService entityOwnershipService,
103 final IdManagerService idManager, final InterfaceManagerRpcService interfaceManagerRpcService) {
104 this.dataBroker = dataBroker;
105 this.entityOwnershipService = entityOwnershipService;
106 this.idManager = idManager;
107 this.interfaceManagerRpcService = interfaceManagerRpcService;
111 @SuppressWarnings("checkstyle:IllegalCatch")
112 public void start() {
114 INTERFACE_STATUS_MONITOR.registerMbean();
116 IfmClusterUtils.registerEntityForOwnership(this, this.entityOwnershipService);
117 BatchingUtils.registerWithBatchManager(this.dataBroker);
118 this.ifaceToTpMap = new ConcurrentHashMap<>();
119 this.ifaceToNodeIidMap = new ConcurrentHashMap<>();
120 this.nodeIidToBridgeMap = new ConcurrentHashMap<>();
122 INTERFACE_STATUS_MONITOR.reportStatus("OPERATIONAL");
123 } catch (Exception e) {
124 INTERFACE_STATUS_MONITOR.reportStatus("ERROR");
127 LOG.info("InterfacemgrProvider Started");
132 public void close() throws Exception {
133 INTERFACE_STATUS_MONITOR.unregisterMbean();
134 LOG.info("InterfacemgrProvider Closed");
137 public EntityOwnershipService getEntityOwnershipService() {
138 return entityOwnershipService;
141 public DataBroker getDataBroker() {
142 return this.dataBroker;
145 private void createIdPool() {
146 CreateIdPoolInput createPool = new CreateIdPoolInputBuilder().setPoolName(IfmConstants.IFM_IDPOOL_NAME)
147 .setLow(IfmConstants.IFM_ID_POOL_START).setHigh(IfmConstants.IFM_ID_POOL_END).build();
148 // TODO: Error handling
149 Future<RpcResult<Void>> result = idManager.createIdPool(createPool);
151 if (result != null && result.get().isSuccessful()) {
152 LOG.debug("Created IdPool for InterfaceMgr");
154 } catch (InterruptedException | ExecutionException e) {
155 LOG.error("Failed to create idPool for InterfaceMgr", e);
160 public Long getPortForInterface(String ifName) {
161 GetPortFromInterfaceInput input = new GetPortFromInterfaceInputBuilder().setIntfName(ifName).build();
162 Future<RpcResult<GetPortFromInterfaceOutput>> output = interfaceManagerRpcService.getPortFromInterface(input);
164 RpcResult<GetPortFromInterfaceOutput> port = output.get();
165 if (port.isSuccessful()) {
166 return port.getResult().getPortno();
168 } catch (NullPointerException | InterruptedException | ExecutionException e) {
169 LOG.warn("Exception when getting port for interface", e);
175 public Long getPortForInterface(Interface intf) {
176 GetPortFromInterfaceInput input = new GetPortFromInterfaceInputBuilder().setIntfName(intf.getName()).build();
177 Future<RpcResult<GetPortFromInterfaceOutput>> output = interfaceManagerRpcService.getPortFromInterface(input);
179 RpcResult<GetPortFromInterfaceOutput> port = output.get();
180 if (port.isSuccessful()) {
181 return port.getResult().getPortno();
183 } catch (NullPointerException | InterruptedException | ExecutionException e) {
184 LOG.warn("Exception when getting port for interface", e);
190 public InterfaceInfo getInterfaceInfo(String interfaceName) {
192 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
193 .ietf.interfaces.rev140508.interfaces.state.Interface ifState = InterfaceManagerCommonUtils
194 .getInterfaceState(interfaceName, dataBroker);
196 if (ifState == null) {
197 LOG.error("Interface {} is not present", interfaceName);
201 Interface intf = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(new InterfaceKey(interfaceName),
204 LOG.error("Interface {} doesn't exist in config datastore", interfaceName);
208 NodeConnectorId ncId = IfmUtil.getNodeConnectorIdFromInterface(intf.getName(), dataBroker);
209 InterfaceInfo.InterfaceType interfaceType = IfmUtil.getInterfaceType(intf);
210 InterfaceInfo interfaceInfo = new InterfaceInfo(interfaceName);
211 BigInteger dpId = org.opendaylight.genius.interfacemanager.globals.IfmConstants.INVALID_DPID;
212 Integer portNo = org.opendaylight.genius.interfacemanager.globals.IfmConstants.INVALID_PORT_NO;
214 dpId = IfmUtil.getDpnFromNodeConnectorId(ncId);
215 portNo = Integer.parseInt(IfmUtil.getPortNoFromNodeConnectorId(ncId));
217 if (interfaceType == InterfaceInfo.InterfaceType.VLAN_INTERFACE) {
218 interfaceInfo = IfmUtil.getVlanInterfaceInfo(interfaceName, intf, dpId);
219 } else if (interfaceType == InterfaceInfo.InterfaceType.UNKNOWN_INTERFACE) {
220 LOG.error("Type of Interface {} is unknown", interfaceName);
223 InterfaceInfo.InterfaceOpState opState;
224 if (ifState.getOperStatus() == OperStatus.Up) {
225 opState = InterfaceInfo.InterfaceOpState.UP;
226 } else if (ifState.getOperStatus() == OperStatus.Down) {
227 opState = InterfaceInfo.InterfaceOpState.DOWN;
229 opState = InterfaceInfo.InterfaceOpState.UNKNOWN;
231 interfaceInfo.setDpId(dpId);
232 interfaceInfo.setPortNo(portNo);
233 interfaceInfo.setAdminState(intf.isEnabled() ? InterfaceAdminState.ENABLED : InterfaceAdminState.DISABLED);
234 interfaceInfo.setInterfaceName(interfaceName);
235 Integer lportTag = ifState.getIfIndex();
236 interfaceInfo.setInterfaceTag(lportTag);
237 interfaceInfo.setInterfaceType(interfaceType);
238 interfaceInfo.setGroupId(IfmUtil.getGroupId(lportTag, interfaceType));
239 interfaceInfo.setOpState(opState);
240 PhysAddress phyAddress = ifState.getPhysAddress();
241 if (phyAddress != null) {
242 interfaceInfo.setMacAddress(ifState.getPhysAddress().getValue());
245 return interfaceInfo;
250 public InterfaceInfo getInterfaceInfoFromOperationalDataStore(String interfaceName,
251 InterfaceInfo.InterfaceType interfaceType) {
252 InterfaceInfo interfaceInfo = new InterfaceInfo(interfaceName);
253 org.opendaylight.yang.gen.v1.urn
254 .ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState =
255 InterfaceManagerCommonUtils
256 .getInterfaceState(interfaceName, dataBroker);
257 if (ifState == null) {
258 LOG.error("Interface {} is not present", interfaceName);
261 NodeConnectorId ncId = IfmUtil.getNodeConnectorIdFromInterface(ifState);
263 interfaceInfo.setDpId(IfmUtil.getDpnFromNodeConnectorId(ncId));
264 interfaceInfo.setPortNo(Integer.parseInt(IfmUtil.getPortNoFromNodeConnectorId(ncId)));
266 InterfaceInfo.InterfaceOpState opState;
267 if (ifState.getOperStatus() == OperStatus.Up) {
268 opState = InterfaceInfo.InterfaceOpState.UP;
269 } else if (ifState.getOperStatus() == OperStatus.Down) {
270 opState = InterfaceInfo.InterfaceOpState.DOWN;
272 opState = InterfaceInfo.InterfaceOpState.UNKNOWN;
274 interfaceInfo.setAdminState(ifState.getAdminStatus() == AdminStatus.Up ? InterfaceAdminState.ENABLED
275 : InterfaceAdminState.DISABLED);
276 interfaceInfo.setInterfaceName(interfaceName);
277 Integer lportTag = ifState.getIfIndex();
278 interfaceInfo.setInterfaceTag(lportTag);
279 interfaceInfo.setInterfaceType(interfaceType);
280 interfaceInfo.setGroupId(IfmUtil.getGroupId(lportTag, interfaceType));
281 interfaceInfo.setOpState(opState);
282 PhysAddress phyAddress = ifState.getPhysAddress();
283 if (phyAddress != null) {
284 interfaceInfo.setMacAddress(ifState.getPhysAddress().getValue());
286 return interfaceInfo;
290 public InterfaceInfo getInterfaceInfoFromOperationalDataStore(String interfaceName) {
291 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
292 .ietf.interfaces.rev140508.interfaces.state.Interface ifState = InterfaceManagerCommonUtils
293 .getInterfaceState(interfaceName, dataBroker);
294 if (ifState == null) {
295 LOG.error("Interface {} is not present", interfaceName);
299 return populateInterfaceInfo(interfaceName, ifState);
302 public InterfaceInfo populateInterfaceInfo(String interfaceName,
303 org.opendaylight.yang.gen.v1.urn
304 .ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState) {
305 InterfaceInfo interfaceInfo = new InterfaceInfo(interfaceName);
306 NodeConnectorId ncId = IfmUtil.getNodeConnectorIdFromInterface(ifState);
308 if (Tunnel.class.equals(ifState.getType())) {
309 interfaceInfo.setPortName(interfaceName);
311 Interface iface = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceName, dataBroker);
313 ParentRefs parentRefs = iface.getAugmentation(ParentRefs.class);
314 interfaceInfo.setPortName(parentRefs.getParentInterface());
317 interfaceInfo.setDpId(IfmUtil.getDpnFromNodeConnectorId(ncId));
318 interfaceInfo.setPortNo(Integer.parseInt(IfmUtil.getPortNoFromNodeConnectorId(ncId)));
320 InterfaceInfo.InterfaceOpState opState;
321 if (ifState.getOperStatus() == OperStatus.Up) {
322 opState = InterfaceInfo.InterfaceOpState.UP;
323 } else if (ifState.getOperStatus() == OperStatus.Down) {
324 opState = InterfaceInfo.InterfaceOpState.DOWN;
326 opState = InterfaceInfo.InterfaceOpState.UNKNOWN;
328 interfaceInfo.setAdminState(ifState.getAdminStatus() == AdminStatus.Up ? InterfaceAdminState.ENABLED
329 : InterfaceAdminState.DISABLED);
330 interfaceInfo.setInterfaceName(interfaceName);
331 Integer lportTag = ifState.getIfIndex();
332 if (lportTag != null) {
333 interfaceInfo.setInterfaceTag(lportTag);
335 interfaceInfo.setOpState(opState);
336 PhysAddress phyAddress = ifState.getPhysAddress();
337 if (phyAddress != null) {
338 interfaceInfo.setMacAddress(ifState.getPhysAddress().getValue());
340 return interfaceInfo;
344 public InterfaceInfo getInterfaceInfoFromOperationalDSCache(String interfaceName) {
345 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
346 .ietf.interfaces.rev140508.interfaces.state.Interface ifState = InterfaceManagerCommonUtils
347 .getInterfaceStateFromCache(interfaceName);
348 if (ifState == null) {
349 LOG.warn("Interface {} is not present", interfaceName);
352 return populateInterfaceInfo(interfaceName, ifState);
356 public Interface getInterfaceInfoFromConfigDataStore(String interfaceName) {
357 return InterfaceManagerCommonUtils.getInterfaceFromConfigDS(new InterfaceKey(interfaceName), dataBroker);
361 public void createVLANInterface(String interfaceName, String portName, BigInteger dpId, Integer vlanId,
362 String description, IfL2vlan.L2vlanMode l2vlanMode) throws InterfaceAlreadyExistsException {
363 createVLANInterface(interfaceName, portName, dpId, vlanId, description, l2vlanMode, false);
367 public void createVLANInterface(String interfaceName, String portName, BigInteger dpId, Integer vlanId,
368 String description, IfL2vlan.L2vlanMode l2vlanMode, boolean isExternal)
369 throws InterfaceAlreadyExistsException {
371 LOG.info("Create VLAN interface : {}", interfaceName);
372 Interface interfaceOptional = InterfaceManagerCommonUtils
373 .getInterfaceFromConfigDS(new InterfaceKey(interfaceName), dataBroker);
374 if (interfaceOptional != null) {
375 LOG.debug("VLAN interface is already exist", interfaceOptional.getDescription());
376 throw new InterfaceAlreadyExistsException(interfaceOptional.getName());
378 IfL2vlanBuilder l2vlanBuilder = new IfL2vlanBuilder().setL2vlanMode(l2vlanMode);
379 if (vlanId != null && vlanId > 0) {
380 l2vlanBuilder.setVlanId(new VlanId(vlanId));
382 ParentRefs parentRefs = new ParentRefsBuilder().setParentInterface(portName).build();
383 InterfaceBuilder interfaceBuilder = new InterfaceBuilder().setEnabled(true).setName(interfaceName)
384 .setType(L2vlan.class).addAugmentation(IfL2vlan.class, l2vlanBuilder.build())
385 .addAugmentation(ParentRefs.class, parentRefs).setDescription(description);
387 interfaceBuilder.addAugmentation(IfExternal.class, new IfExternalBuilder().setExternal(true).build());
389 InstanceIdentifier<Interface> interfaceInstanceIdentifier = InterfaceManagerCommonUtils
390 .getInterfaceIdentifier(new InterfaceKey(interfaceName));
391 WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
392 writeTransaction.put(LogicalDatastoreType.CONFIGURATION, interfaceInstanceIdentifier, interfaceBuilder.build(),
394 writeTransaction.submit();
397 private boolean isServiceBoundOnInterface(short servicePriority, String interfaceName,
398 Class<? extends ServiceModeBase> serviceMode) {
399 InstanceIdentifier<BoundServices> boundServicesIId = IfmUtil.buildBoundServicesIId(servicePriority,
400 interfaceName, serviceMode);
402 return SingleTransactionDataBroker
403 .syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION, boundServicesIId).isPresent();
404 } catch (ReadFailedException e) {
405 LOG.warn("Error while reading [{}]", boundServicesIId, e);
411 public boolean isServiceBoundOnInterfaceForIngress(short servicePriority, String interfaceName) {
412 return isServiceBoundOnInterface(servicePriority, interfaceName, ServiceModeIngress.class);
416 public boolean isServiceBoundOnInterfaceForEgress(short servicePriority, String interfaceName) {
417 return isServiceBoundOnInterface(servicePriority, interfaceName, ServiceModeEgress.class);
421 public void bindService(String interfaceName, Class<? extends ServiceModeBase> serviceMode,
422 BoundServices serviceInfo) {
423 bindService(interfaceName, serviceMode, serviceInfo, /* WriteTransaction */ null);
427 public void bindService(String interfaceName, Class<? extends ServiceModeBase> serviceMode,
428 BoundServices serviceInfo, WriteTransaction tx) {
429 WriteTransaction writeTransaction = tx != null ? tx : dataBroker.newWriteOnlyTransaction();
430 IfmUtil.bindService(writeTransaction, interfaceName, serviceInfo, serviceMode);
432 writeTransaction.submit();
437 public void unbindService(String interfaceName, Class<? extends ServiceModeBase> serviceMode,
438 BoundServices serviceInfo) {
439 IfmUtil.unbindService(dataBroker, interfaceName,
440 FlowBasedServicesUtils.buildServiceId(interfaceName, serviceInfo.getServicePriority(), serviceMode));
444 public BigInteger getDpnForInterface(Interface intrf) {
445 return getDpnForInterface(intrf.getName());
449 public BigInteger getDpnForInterface(String ifName) {
450 GetDpidFromInterfaceInput input = new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
451 Future<RpcResult<GetDpidFromInterfaceOutput>> output = interfaceManagerRpcService.getDpidFromInterface(input);
453 RpcResult<GetDpidFromInterfaceOutput> dpn = output.get();
454 if (dpn.isSuccessful()) {
455 return dpn.getResult().getDpid();
457 } catch (NullPointerException | InterruptedException | ExecutionException e) {
458 LOG.warn("Exception when getting port for interface", e);
464 public String getEndpointIpForDpn(BigInteger dpnId) {
465 GetEndpointIpForDpnInput input = new GetEndpointIpForDpnInputBuilder().setDpid(dpnId).build();
466 Future<RpcResult<GetEndpointIpForDpnOutput>> output = interfaceManagerRpcService.getEndpointIpForDpn(input);
468 RpcResult<GetEndpointIpForDpnOutput> ipForDpnOutputRpcResult = output.get();
469 if (ipForDpnOutputRpcResult.isSuccessful()) {
470 List<IpAddress> localIps = ipForDpnOutputRpcResult.getResult().getLocalIps();
471 if (!localIps.isEmpty()) {
472 return localIps.get(0).getIpv4Address().getValue();
475 } catch (NullPointerException | InterruptedException | ExecutionException e) {
476 LOG.warn("Exception when getting port for interface", e);
482 public List<ActionInfo> getInterfaceEgressActions(String ifName) {
483 return IfmUtil.getEgressActionInfosForInterface(ifName, 0, dataBroker, false);
487 public List<Interface> getVlanInterfaces() {
488 return InterfaceManagerCommonUtils.getAllVlanInterfacesFromCache();
492 public List<Interface> getVxlanInterfaces() {
493 return InterfaceManagerCommonUtils.getAllTunnelInterfacesFromCache();
497 public List<Interface> getChildInterfaces(String parentInterface) {
498 InterfaceParentEntry parentEntry = InterfaceMetaUtils.getInterfaceParentEntryFromConfigDS(parentInterface,
500 if (parentEntry == null) {
501 LOG.debug("No parent entry found for {}", parentInterface);
502 return Collections.emptyList();
505 List<InterfaceChildEntry> childEntries = parentEntry.getInterfaceChildEntry();
506 if (childEntries == null || childEntries.isEmpty()) {
507 LOG.debug("No child entries found for parent {}", parentInterface);
508 return Collections.emptyList();
511 List<Interface> childInterfaces = new ArrayList<>();
512 for (InterfaceChildEntry childEntry : childEntries) {
513 String interfaceName = childEntry.getChildInterface();
514 Interface iface = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceName, dataBroker);
516 childInterfaces.add(iface);
518 LOG.debug("Child interface {} not found in config DS for parent interface {}", interfaceName,
523 LOG.trace("Found child interfaces {} for parent {}", childInterfaces, parentInterface);
524 return childInterfaces;
528 public boolean isExternalInterface(String interfaceName) {
529 return isExternalInterface(getInterfaceInfoFromConfigDataStore(interfaceName));
532 private boolean isExternalInterface(Interface iface) {
537 IfExternal ifExternal = iface.getAugmentation(IfExternal.class);
538 return ifExternal != null && Boolean.TRUE.equals(ifExternal.isExternal());
542 public String getPortNameForInterface(NodeConnectorId nodeConnectorId, String interfaceName) {
543 return InterfaceManagerCommonUtils.getPortNameForInterface(nodeConnectorId, interfaceName);
547 public String getPortNameForInterface(String dpnId, String interfaceName) {
548 return InterfaceManagerCommonUtils.getPortNameForInterface(dpnId, interfaceName);
552 public Map<String, OvsdbTerminationPointAugmentation> getTerminationPointCache() {
553 return new ConcurrentHashMap<>(this.ifaceToTpMap);
556 public void addTerminationPointForInterface(String interfaceName,
557 OvsdbTerminationPointAugmentation terminationPoint) {
558 LOG.debug("Adding TerminationPoint {} to cache for Interface {}", terminationPoint.getName(), interfaceName);
559 if (interfaceName != null && terminationPoint != null) {
560 ifaceToTpMap.put(interfaceName, terminationPoint);
564 public OvsdbTerminationPointAugmentation getTerminationPoint(String interfaceName) {
565 return ifaceToTpMap.get(interfaceName);
568 public void removeTerminationPointForInterface(String interfaceName) {
569 LOG.debug("Removing TerminationPoint from cache for Interface {}", interfaceName);
570 if (interfaceName != null) {
571 ifaceToTpMap.remove(interfaceName);
575 public void addNodeIidForInterface(String interfaceName, InstanceIdentifier<Node> nodeIid) {
576 if (interfaceName != null && nodeIid != null) {
577 ifaceToNodeIidMap.put(interfaceName, nodeIid);
581 public void removeNodeIidForInterface(String interfaceName) {
582 if (interfaceName != null) {
583 ifaceToNodeIidMap.remove(interfaceName);
587 public InstanceIdentifier<Node> getNodeIidForInterface(String interfaceName) {
588 if (interfaceName != null) {
589 return ifaceToNodeIidMap.get(interfaceName);
594 private OvsdbBridgeAugmentation getBridgeForInterface(String interfaceName,
595 InstanceIdentifier<Node> nodeInstanceId) {
596 InstanceIdentifier<Node> nodeIid = nodeInstanceId;
597 if (nodeIid == null) {
598 nodeIid = getNodeIidForInterface(interfaceName);
600 return getBridgeForNodeIid(nodeIid);
603 public String getDpidForInterface(String interfaceName) {
604 return getDpidForInterface(interfaceName, null);
607 public String getDpidForInterface(String interfaceName, InstanceIdentifier<Node> nodeInstanceId) {
608 OvsdbBridgeAugmentation bridge = getBridgeForInterface(interfaceName, nodeInstanceId);
609 if (bridge != null) {
610 BigInteger dpid = IfmUtil.getDpnId(bridge.getDatapathId());
611 if (dpid != null && dpid.longValue() != 0) {
612 return String.valueOf(dpid);
618 public void addBridgeForNodeIid(InstanceIdentifier<Node> nodeIid, OvsdbBridgeAugmentation bridge) {
619 if (nodeIid != null && bridge != null) {
620 nodeIidToBridgeMap.put(nodeIid, bridge);
624 public void removeBridgeForNodeIid(InstanceIdentifier<Node> nodeIid) {
625 if (nodeIid != null) {
626 nodeIidToBridgeMap.remove(nodeIid);
630 public OvsdbBridgeAugmentation getBridgeForNodeIid(InstanceIdentifier<Node> nodeIid) {
631 if (nodeIid != null) {
632 return nodeIidToBridgeMap.get(nodeIid);
638 public String getParentRefNameForInterface(String interfaceName) {
639 String parentRefName = null;
641 String dpnId = getDpidForInterface(interfaceName, null);
642 OvsdbTerminationPointAugmentation ovsdbTp = getTerminationPoint(interfaceName);
643 if (ovsdbTp != null) {
645 LOG.error("Got NULL dpnId when looking for TP with external ID {}", interfaceName);
648 parentRefName = getPortNameForInterface(dpnId, ovsdbTp.getName());
649 LOG.debug("Building parent ref for interface {}, using parentRefName {} acquired by external ID",
650 interfaceName, parentRefName);
652 LOG.debug("Skipping parent ref for interface {}, as there is no termination point that references "
653 + "this interface yet.", interfaceName);
656 return parentRefName;
660 public void updateInterfaceParentRef(String interfaceName, String parentInterface) {
661 // This should generally be called by EOS Owner for
662 // INTERFACE_CONFIG_ENTITY - runOnlyInLeaderNode()
663 updateInterfaceParentRef(interfaceName, parentInterface, true);
667 public void updateInterfaceParentRef(String interfaceName, String parentInterface,
668 boolean readInterfaceBeforeWrite) {
669 // This should generally be called by EOS Owner for
670 // INTERFACE_CONFIG_ENTITY - runOnlyInLeaderNode()
671 if (interfaceName == null) {
675 DataStoreJobCoordinator jobCoordinator = DataStoreJobCoordinator.getInstance();
676 ParentRefUpdateWorker parentRefUpdateWorker = new ParentRefUpdateWorker(interfaceName, parentInterface,
677 readInterfaceBeforeWrite);
678 jobCoordinator.enqueueJob(interfaceName, parentRefUpdateWorker, IfmConstants.JOB_MAX_RETRIES);
681 public class ParentRefUpdateWorker implements Callable<List<ListenableFuture<Void>>> {
682 String interfaceName;
683 String parentInterfaceName;
684 Boolean readInterfaceBeforeWrite;
686 public ParentRefUpdateWorker(String interfaceName, String parentInterfaceName,
687 boolean readInterfaceBeforeWrite) {
688 this.interfaceName = interfaceName;
689 this.parentInterfaceName = parentInterfaceName;
690 this.readInterfaceBeforeWrite = readInterfaceBeforeWrite;
694 public List<ListenableFuture<Void>> call() throws Exception {
695 if (readInterfaceBeforeWrite) {
696 Interface iface = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceName, dataBroker);
698 LOG.debug("Interface doesn't exist in config DS - no need to update parentRef, skipping");
702 WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
703 IfmUtil.updateInterfaceParentRef(writeTransaction, interfaceName, parentInterfaceName);
704 return Collections.singletonList(writeTransaction.submit());
709 public OvsdbTerminationPointAugmentation getTerminationPointForInterface(String interfaceName) {
710 return getTerminationPoint(interfaceName);
714 public OvsdbBridgeAugmentation getOvsdbBridgeForInterface(String interfaceName) {
715 return getBridgeForInterface(interfaceName, null);
719 public OvsdbBridgeAugmentation getOvsdbBridgeForNodeIid(InstanceIdentifier<Node> nodeIid) {
720 return getBridgeForNodeIid(nodeIid);
725 * Get all termination points on a given DPN.
726 * This API uses read on Operational DS. If there are perf issues in cluster
727 * setup, we can consider caching later.
730 * Datapath Node Identifier
732 * @return If the data at the supplied path exists, returns a list of all termination point
735 public List<OvsdbTerminationPointAugmentation> getPortsOnBridge(BigInteger dpnId) {
736 List<OvsdbTerminationPointAugmentation> ports = new ArrayList<>();
737 List<TerminationPoint> portList = IfmUtil.getTerminationPointsOnBridge(dataBroker, dpnId);
738 for (TerminationPoint ovsPort : portList) {
739 if (ovsPort.getAugmentation(OvsdbTerminationPointAugmentation.class) != null) {
740 ports.add(ovsPort.getAugmentation(OvsdbTerminationPointAugmentation.class));
743 LOG.debug("Found {} ports on bridge {}", ports.size(), dpnId);
748 * Get all termination points of type tunnel on a given DPN.
751 * Datapath Node Identifier
753 * @return If the data at the supplied path exists, returns a list of all termination point
754 * Augmentations of type tunnel
757 public List<OvsdbTerminationPointAugmentation> getTunnelPortsOnBridge(BigInteger dpnId) {
758 List<OvsdbTerminationPointAugmentation> tunnelPorts = new ArrayList<>();
759 List<TerminationPoint> portList = IfmUtil.getTerminationPointsOnBridge(dataBroker, dpnId);
760 for (TerminationPoint ovsPort : portList) {
761 OvsdbTerminationPointAugmentation portAug =
762 ovsPort.getAugmentation(OvsdbTerminationPointAugmentation.class);
763 if (portAug != null && SouthboundUtils.isInterfaceTypeTunnel(portAug.getInterfaceType())) {
764 tunnelPorts.add(portAug);
768 LOG.debug("Found {} tunnel ports on bridge {}", tunnelPorts.size(), dpnId);
773 * Get all termination points by type on a given DPN.
776 * Datapath Node Identifier
778 * @return If the data at the supplied path exists, returns a Map where key is interfaceType
779 * and value is list of termination points of given type
782 public Map<Class<? extends InterfaceTypeBase>, List<OvsdbTerminationPointAugmentation>>
783 getPortsOnBridgeByType(BigInteger dpnId) {
785 Map<Class<? extends InterfaceTypeBase>, List<OvsdbTerminationPointAugmentation>> portMap;
786 portMap = new ConcurrentHashMap<>();
787 List<TerminationPoint> ovsPorts = IfmUtil.getTerminationPointsOnBridge(dataBroker, dpnId);
788 if (ovsPorts != null) {
789 for (TerminationPoint ovsPort : ovsPorts) {
790 OvsdbTerminationPointAugmentation portAug =
791 ovsPort.getAugmentation(OvsdbTerminationPointAugmentation.class);
792 if (portAug != null && portAug.getInterfaceType() != null) {
793 portMap.computeIfAbsent(portAug.getInterfaceType(), k -> new ArrayList<>()).add(portAug);
801 public long getLogicalTunnelSelectGroupId(int lportTag) {
802 return IfmUtil.getLogicalTunnelSelectGroupId(lportTag);