2 * Copyright (c) 2016 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;
11 import com.google.common.util.concurrent.CheckedFuture;
12 import com.google.common.util.concurrent.ListenableFuture;
14 import java.math.BigInteger;
15 import java.util.ArrayList;
16 import java.util.List;
17 import java.util.concurrent.Callable;
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.controller.md.sal.common.api.data.TransactionCommitFailedException;
30 import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
31 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
32 import org.opendaylight.genius.interfacemanager.commons.InterfaceManagerCommonUtils;
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.rpcservice.InterfaceManagerRpcService;
40 import org.opendaylight.genius.interfacemanager.servicebindings.flowbased.utilities.FlowBasedServicesUtils;
41 import org.opendaylight.genius.interfacemanager.servicebindings.flowbased.utilities.FlowBasedServicesUtils.ServiceMode;
42 import org.opendaylight.genius.interfacemanager.statusanddiag.InterfaceStatusMonitor;
43 import org.opendaylight.genius.mdsalutil.ActionInfo;
44 import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
45 import org.opendaylight.ovsdb.utils.southbound.utils.SouthboundUtils;
46 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel;
48 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
49 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
50 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
51 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
52 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus;
53 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus;
54 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeBase;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServices;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInput;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInputBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
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.rpcs.rev160406.OdlInterfaceRpcService;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeBase;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeEgress;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeIngress;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServices;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
85 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
86 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
87 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
88 import org.opendaylight.yangtools.yang.common.RpcResult;
89 import org.slf4j.Logger;
90 import org.slf4j.LoggerFactory;
93 public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
95 private static final Logger LOG = LoggerFactory.getLogger(InterfacemgrProvider.class);
96 private static final InterfaceStatusMonitor interfaceStatusMonitor = InterfaceStatusMonitor.getInstance();
97 private final DataBroker dataBroker;
98 private final IdManagerService idManager;
99 private final InterfaceManagerRpcService interfaceManagerRpcService;
100 private final EntityOwnershipService entityOwnershipService;
101 private final MdsalUtils mdsalUtils;
102 private final SouthboundUtils southboundUtils;
105 public InterfacemgrProvider(final DataBroker dataBroker, final EntityOwnershipService entityOwnershipService,
106 final IdManagerService idManager,
107 final InterfaceManagerRpcService interfaceManagerRpcService){
108 this.dataBroker = dataBroker;
109 this.entityOwnershipService = entityOwnershipService;
110 this.idManager = idManager;
111 this.interfaceManagerRpcService = interfaceManagerRpcService;
112 this.mdsalUtils = new MdsalUtils(dataBroker);
113 this.southboundUtils = new SouthboundUtils(mdsalUtils);
117 @SuppressWarnings("checkstyle:IllegalCatch")
118 public void start() throws Exception {
120 interfaceStatusMonitor.registerMbean();
122 IfmClusterUtils.registerEntityForOwnership(this, this.entityOwnershipService);
123 BatchingUtils.registerWithBatchManager( this.dataBroker);
124 interfaceStatusMonitor.reportStatus("OPERATIONAL");
125 } catch (Exception e) {
126 interfaceStatusMonitor.reportStatus("ERROR");
129 LOG.info("InterfacemgrProvider Started");
134 public void close() throws Exception {
135 LOG.info("InterfacemgrProvider Closed");
138 public EntityOwnershipService getEntityOwnershipService() {
139 return entityOwnershipService;
142 public DataBroker getDataBroker(){
143 return this.dataBroker;
146 private void createIdPool() {
147 CreateIdPoolInput createPool = new CreateIdPoolInputBuilder()
148 .setPoolName(IfmConstants.IFM_IDPOOL_NAME)
149 .setLow(IfmConstants.IFM_ID_POOL_START)
150 .setHigh(IfmConstants.IFM_ID_POOL_END)
152 //TODO: Error handling
153 Future<RpcResult<Void>> result = idManager.createIdPool(createPool);
155 if (result != null && result.get().isSuccessful()) {
156 LOG.debug("Created IdPool for InterfaceMgr");
158 } catch (InterruptedException | ExecutionException e) {
159 LOG.error("Failed to create idPool for InterfaceMgr", e);
164 public Long getPortForInterface(String ifName) {
165 GetPortFromInterfaceInput input = new GetPortFromInterfaceInputBuilder().setIntfName(ifName).build();
166 Future<RpcResult<GetPortFromInterfaceOutput>> output = interfaceManagerRpcService.getPortFromInterface(input);
168 RpcResult<GetPortFromInterfaceOutput> port = output.get();
169 if (port.isSuccessful()) {
170 return port.getResult().getPortno();
172 } catch (NullPointerException | InterruptedException | ExecutionException e) {
173 LOG.warn("Exception when getting port for interface", e);
179 public Long getPortForInterface(Interface intf) {
180 GetPortFromInterfaceInput input = new GetPortFromInterfaceInputBuilder().setIntfName(intf.getName()).build();
181 Future<RpcResult<GetPortFromInterfaceOutput>> output = interfaceManagerRpcService.getPortFromInterface(input);
183 RpcResult<GetPortFromInterfaceOutput> port = output.get();
184 if (port.isSuccessful()) {
185 return port.getResult().getPortno();
187 } catch (NullPointerException | InterruptedException | ExecutionException e) {
188 LOG.warn("Exception when getting port for interface", e);
194 public InterfaceInfo getInterfaceInfo(String interfaceName) {
196 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface
197 ifState = InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(interfaceName, dataBroker);
199 if (ifState == null) {
200 LOG.error("Interface {} is not present", interfaceName);
204 Integer lportTag = ifState.getIfIndex();
205 Interface intf = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(new InterfaceKey(interfaceName), dataBroker);
207 LOG.error("Interface {} doesn't exist in config datastore", interfaceName);
211 NodeConnectorId ncId = IfmUtil.getNodeConnectorIdFromInterface(intf.getName(), dataBroker);
212 InterfaceInfo.InterfaceType interfaceType = IfmUtil.getInterfaceType(intf);
213 InterfaceInfo interfaceInfo = new InterfaceInfo(interfaceName);
214 BigInteger dpId = org.opendaylight.genius.interfacemanager.globals.IfmConstants.INVALID_DPID;
215 Integer portNo = org.opendaylight.genius.interfacemanager.globals.IfmConstants.INVALID_PORT_NO;
217 dpId = IfmUtil.getDpnFromNodeConnectorId(ncId);
218 portNo = Integer.parseInt(IfmUtil.getPortNoFromNodeConnectorId(ncId));
220 if (interfaceType == InterfaceInfo.InterfaceType.VLAN_INTERFACE) {
221 interfaceInfo = IfmUtil.getVlanInterfaceInfo(interfaceName, intf, dpId);
222 } else if (interfaceType == InterfaceInfo.InterfaceType.VXLAN_TRUNK_INTERFACE ||
223 interfaceType == InterfaceInfo.InterfaceType.GRE_TRUNK_INTERFACE) {
224 // TODO : since there is no logical grouping for tunnel interfaces, there is no need
225 // for this code as of now. will be revisited once the support comes
228 LOG.error("Type of Interface {} is unknown", interfaceName);
231 InterfaceInfo.InterfaceOpState opState ;
232 if(ifState.getOperStatus() == OperStatus.Up)
234 opState = InterfaceInfo.InterfaceOpState.UP;
236 else if (ifState.getOperStatus() == OperStatus.Down)
238 opState = InterfaceInfo.InterfaceOpState.DOWN;
242 opState = InterfaceInfo.InterfaceOpState.UNKNOWN;
244 interfaceInfo.setDpId(dpId);
245 interfaceInfo.setPortNo(portNo);
246 interfaceInfo.setAdminState(intf.isEnabled() ? InterfaceAdminState.ENABLED : InterfaceAdminState.DISABLED);
247 interfaceInfo.setInterfaceName(interfaceName);
248 interfaceInfo.setInterfaceTag(lportTag);
249 interfaceInfo.setInterfaceType(interfaceType);
250 interfaceInfo.setGroupId(IfmUtil.getGroupId(lportTag, interfaceType));
251 interfaceInfo.setOpState(opState);
252 PhysAddress phyAddress = ifState.getPhysAddress();
253 if (phyAddress != null) {
254 interfaceInfo.setMacAddress(ifState.getPhysAddress().getValue());
257 return interfaceInfo;
262 public InterfaceInfo getInterfaceInfoFromOperationalDataStore(String interfaceName, InterfaceInfo.InterfaceType interfaceType) {
263 InterfaceInfo interfaceInfo = new InterfaceInfo(interfaceName);
264 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState = InterfaceManagerCommonUtils
265 .getInterfaceStateFromOperDS(interfaceName, dataBroker);
266 if (ifState == null) {
267 LOG.error("Interface {} is not present", interfaceName);
270 Integer lportTag = ifState.getIfIndex();
271 NodeConnectorId ncId = IfmUtil.getNodeConnectorIdFromInterface(ifState);
273 interfaceInfo.setDpId(IfmUtil.getDpnFromNodeConnectorId(ncId));
274 interfaceInfo.setPortNo(Integer.parseInt(IfmUtil.getPortNoFromNodeConnectorId(ncId)));
276 InterfaceInfo.InterfaceOpState opState ;
277 if(ifState.getOperStatus() == OperStatus.Up)
279 opState = InterfaceInfo.InterfaceOpState.UP;
281 else if (ifState.getOperStatus() == OperStatus.Down)
283 opState = InterfaceInfo.InterfaceOpState.DOWN;
287 opState = InterfaceInfo.InterfaceOpState.UNKNOWN;
289 interfaceInfo.setAdminState(ifState.getAdminStatus() == AdminStatus.Up ? InterfaceAdminState.ENABLED : InterfaceAdminState.DISABLED);
290 interfaceInfo.setInterfaceName(interfaceName);
291 interfaceInfo.setInterfaceTag(lportTag);
292 interfaceInfo.setInterfaceType(interfaceType);
293 interfaceInfo.setGroupId(IfmUtil.getGroupId(lportTag, interfaceType));
294 interfaceInfo.setOpState(opState);
295 PhysAddress phyAddress = ifState.getPhysAddress();
296 if (phyAddress != null) {
297 interfaceInfo.setMacAddress(ifState.getPhysAddress().getValue());
300 return interfaceInfo;
304 public InterfaceInfo getInterfaceInfoFromOperationalDataStore(String interfaceName) {
305 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface
306 ifState = InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(interfaceName, dataBroker);
307 if (ifState == null) {
308 LOG.error("Interface {} is not present", interfaceName);
312 return populateInterfaceInfo(interfaceName, ifState);
316 public InterfaceInfo populateInterfaceInfo(String interfaceName, org.opendaylight.yang.gen.v1.urn.ietf.params.xml
317 .ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState) {
318 Integer lportTag = ifState.getIfIndex();
319 InterfaceInfo interfaceInfo = new InterfaceInfo(interfaceName);
320 NodeConnectorId ncId = IfmUtil.getNodeConnectorIdFromInterface(ifState);
322 if (Tunnel.class.equals(ifState.getType())) {
323 interfaceInfo.setPortName(interfaceName);
325 Interface iface = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceName, dataBroker);
326 ParentRefs parentRefs = iface.getAugmentation(ParentRefs.class);
327 interfaceInfo.setPortName(parentRefs.getParentInterface());
329 interfaceInfo.setDpId(IfmUtil.getDpnFromNodeConnectorId(ncId));
330 interfaceInfo.setPortNo(Integer.parseInt(IfmUtil.getPortNoFromNodeConnectorId(ncId)));
332 InterfaceInfo.InterfaceOpState opState ;
333 if (ifState.getOperStatus() == OperStatus.Up) {
334 opState = InterfaceInfo.InterfaceOpState.UP;
335 } else if (ifState.getOperStatus() == OperStatus.Down) {
336 opState = InterfaceInfo.InterfaceOpState.DOWN;
338 opState = InterfaceInfo.InterfaceOpState.UNKNOWN;
340 interfaceInfo.setAdminState((ifState.getAdminStatus() == AdminStatus.Up) ? InterfaceAdminState.ENABLED
341 : InterfaceAdminState.DISABLED);
342 interfaceInfo.setInterfaceName(interfaceName);
343 if (lportTag != null) {
344 interfaceInfo.setInterfaceTag(lportTag);
346 interfaceInfo.setOpState(opState);
347 PhysAddress phyAddress = ifState.getPhysAddress();
348 if (phyAddress != null) {
349 interfaceInfo.setMacAddress(ifState.getPhysAddress().getValue());
351 return interfaceInfo;
356 public InterfaceInfo getInterfaceInfoFromOperationalDSCache(String interfaceName) {
357 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface
358 ifState = InterfaceManagerCommonUtils.getInterfaceStateFromCache(interfaceName);
359 if (ifState == null) {
360 LOG.warn("Interface {} is not present", interfaceName);
363 return populateInterfaceInfo(interfaceName, ifState);
367 public Interface getInterfaceInfoFromConfigDataStore(String interfaceName) {
368 Interface intf = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(new InterfaceKey(interfaceName), dataBroker);
373 public void createVLANInterface(String interfaceName, String portName, BigInteger dpId, Integer vlanId,
374 String description, IfL2vlan.L2vlanMode l2vlanMode) throws InterfaceAlreadyExistsException {
375 createVLANInterface(interfaceName, portName, dpId, vlanId, description, l2vlanMode, false);
378 public void createVLANInterface(String interfaceName, String portName, BigInteger dpId, Integer vlanId,
379 String description, IfL2vlan.L2vlanMode l2vlanMode, boolean isExternal) throws InterfaceAlreadyExistsException {
381 LOG.info("Create VLAN interface : {}", interfaceName);
382 InstanceIdentifier<Interface> interfaceInstanceIdentifier = InterfaceManagerCommonUtils.getInterfaceIdentifier(new InterfaceKey(interfaceName));
383 Interface interfaceOptional = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(new InterfaceKey(interfaceName), dataBroker);
384 if (interfaceOptional != null) {
385 LOG.debug("VLAN interface is already exist", interfaceOptional.getDescription());
386 throw new InterfaceAlreadyExistsException(interfaceOptional.getName());
388 IfL2vlanBuilder l2vlanBuilder = new IfL2vlanBuilder().setL2vlanMode(l2vlanMode);
389 if (vlanId != null && vlanId > 0) {
390 l2vlanBuilder.setVlanId(new VlanId(vlanId));
392 ParentRefs parentRefs = new ParentRefsBuilder().setParentInterface(portName).build();
393 InterfaceBuilder interfaceBuilder = new InterfaceBuilder().setEnabled(true).setName(interfaceName).setType(L2vlan.class).
394 addAugmentation(IfL2vlan.class, l2vlanBuilder.build()).addAugmentation(ParentRefs.class, parentRefs).
395 setDescription(description);
397 interfaceBuilder.addAugmentation(IfExternal.class, new IfExternalBuilder().setExternal(true).build());
399 WriteTransaction t = dataBroker.newWriteOnlyTransaction();
400 t.put(LogicalDatastoreType.CONFIGURATION, interfaceInstanceIdentifier, interfaceBuilder.build(), true);
404 private boolean isServiceBoundOnInterface(short servicePriority, String interfaceName,
405 Class<? extends ServiceModeBase> serviceMode) {
406 InstanceIdentifier<BoundServices> boundServicesIId =
407 IfmUtil.buildBoundServicesIId(servicePriority, interfaceName, serviceMode);
409 return SingleTransactionDataBroker.syncReadOptional(dataBroker,
410 LogicalDatastoreType.CONFIGURATION, boundServicesIId)
412 } catch (ReadFailedException e) {
413 LOG.warn("Error while reading [{}]", boundServicesIId, e);
419 public boolean isServiceBoundOnInterfaceForIngress(short servicePriority, String interfaceName) {
420 return isServiceBoundOnInterface(servicePriority, interfaceName, ServiceModeIngress.class);
424 public boolean isServiceBoundOnInterfaceForEgress(short servicePriority, String interfaceName) {
425 return isServiceBoundOnInterface(servicePriority, interfaceName, ServiceModeEgress.class);
429 public void bindService(String interfaceName, Class<? extends ServiceModeBase> serviceMode,
430 BoundServices serviceInfo) {
431 bindService(interfaceName, serviceMode, serviceInfo, /*WriteTransaction*/ null);
435 public void bindService(String interfaceName, Class<? extends ServiceModeBase> serviceMode,
436 BoundServices serviceInfo, WriteTransaction tx) {
437 WriteTransaction t = (tx != null) ? tx : dataBroker.newWriteOnlyTransaction();
438 IfmUtil.bindService(t, interfaceName, serviceInfo, serviceMode);
445 public void unbindService(String interfaceName, Class<? extends ServiceModeBase> serviceMode, BoundServices serviceInfo) {
446 IfmUtil.unbindService(dataBroker, interfaceName,
447 FlowBasedServicesUtils.buildServiceId(interfaceName, serviceInfo.getServicePriority(), serviceMode));
451 public BigInteger getDpnForInterface(String ifName) {
452 GetDpidFromInterfaceInput input = new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
453 Future<RpcResult<GetDpidFromInterfaceOutput>> output = interfaceManagerRpcService.getDpidFromInterface(input);
455 RpcResult<GetDpidFromInterfaceOutput> dpn = output.get();
456 if (dpn.isSuccessful()) {
457 return dpn.getResult().getDpid();
459 } catch (NullPointerException | InterruptedException | ExecutionException e) {
460 LOG.warn("Exception when getting port for interface", e);
466 public String getEndpointIpForDpn(BigInteger dpnId) {
467 GetEndpointIpForDpnInput input = new GetEndpointIpForDpnInputBuilder().setDpid(dpnId).build();
468 Future<RpcResult<GetEndpointIpForDpnOutput>> output = interfaceManagerRpcService.getEndpointIpForDpn(input);
470 RpcResult<GetEndpointIpForDpnOutput> ipForDpnOutputRpcResult = output.get();
471 if (ipForDpnOutputRpcResult.isSuccessful()) {
472 List<IpAddress> localIps = ipForDpnOutputRpcResult.getResult().getLocalIps();
473 if (!localIps.isEmpty()) {
474 return localIps.get(0).getIpv4Address().getValue();
477 } catch (NullPointerException | InterruptedException | ExecutionException e) {
478 LOG.warn("Exception when getting port for interface", e);
484 public List<ActionInfo> getInterfaceEgressActions(String ifName) {
485 return IfmUtil.getEgressActionInfosForInterface(ifName, 0, dataBroker, false);
489 public BigInteger getDpnForInterface(Interface intrf) {
490 return getDpnForInterface(intrf.getName());
494 public List<Interface> getVlanInterfaces() {
495 return InterfaceManagerCommonUtils.getAllVlanInterfacesFromCache();
499 public List<Interface> getVxlanInterfaces() {
500 return InterfaceManagerCommonUtils.getAllTunnelInterfacesFromCache();
504 public boolean isExternalInterface(String interfaceName) {
505 return isExternalInterface(getInterfaceInfoFromConfigDataStore(interfaceName));
508 private boolean isExternalInterface(Interface iface) {
513 IfExternal ifExternal = iface.getAugmentation(IfExternal.class);
514 return ifExternal != null && Boolean.TRUE.equals(ifExternal.isExternal());
518 public String getPortNameForInterface(NodeConnectorId nodeConnectorId, String interfaceName) {
519 return InterfaceManagerCommonUtils.getPortNameForInterface(nodeConnectorId, interfaceName);
523 public String getPortNameForInterface(String dpnId, String interfaceName) {
524 return InterfaceManagerCommonUtils.getPortNameForInterface(dpnId, interfaceName);
528 public String getParentRefNameForInterface(String interfaceName) {
529 String parentRefName = null;
531 // FIXME Note this utility isn't very good for scale/performance as it traverses all nodes,
532 // probably need to use a cache instead of these (iface_name->dpnId+tpName).
533 Node node = southboundUtils.getNodeByTerminationPointExternalId(interfaceName);
535 String dpnId = southboundUtils.getDataPathIdStr(node);
537 LOG.error("Got node {} when looking for TP with external ID {}, "
538 + "but unexpectedly got NULL dpnId for this node", node, interfaceName);
541 TerminationPoint tp = SouthboundUtils.getTerminationPointByExternalId(node, interfaceName);
543 LOG.error("Got node {} when looking for TP with external ID {}, "
544 + "but unexpectedly got a NULL TP from this node", node, interfaceName);
547 OvsdbTerminationPointAugmentation ovsdbTp = tp.getAugmentation(OvsdbTerminationPointAugmentation.class);
548 parentRefName = getPortNameForInterface(dpnId, ovsdbTp.getName());
549 LOG.debug("Building parent ref for neutron port {}, using parentRefName {} acquired by external ID",
550 interfaceName, parentRefName);
552 LOG.debug("Skipping parent ref for neutron port {}, as there is no termination point that references "
553 + "this neutron port yet.", interfaceName);
556 return parentRefName;
560 public void updateInterfaceParentRef(String interfaceName, String parentInterface) {
561 // This should generally be called by EOS Owner for INTERFACE_CONFIG_ENTITY - runOnlyInLeaderNode()
562 updateInterfaceParentRef(interfaceName, parentInterface, true);
566 public void updateInterfaceParentRef(String interfaceName, String parentInterface, boolean readInterfaceBeforeWrite) {
567 // This should generally be called by EOS Owner for INTERFACE_CONFIG_ENTITY - runOnlyInLeaderNode()
568 if (interfaceName == null) {
572 DataStoreJobCoordinator jobCoordinator = DataStoreJobCoordinator.getInstance();
573 ParentRefUpdateWorker parentRefUpdateWorker =
574 new ParentRefUpdateWorker(interfaceName, parentInterface, readInterfaceBeforeWrite);
575 jobCoordinator.enqueueJob(interfaceName, parentRefUpdateWorker, IfmConstants.JOB_MAX_RETRIES);
578 public class ParentRefUpdateWorker implements Callable<List<ListenableFuture<Void>>> {
579 String interfaceName;
580 String parentInterfaceName;
581 Boolean readInterfaceBeforeWrite;
583 public ParentRefUpdateWorker(String interfaceName, String parentInterfaceName, boolean readInterfaceBeforeWrite) {
584 this.interfaceName = interfaceName;
585 this.parentInterfaceName = parentInterfaceName;
586 this.readInterfaceBeforeWrite = readInterfaceBeforeWrite;
590 public List<ListenableFuture<Void>> call() throws Exception {
591 if (readInterfaceBeforeWrite) {
592 Interface iface = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceName, dataBroker);
594 LOG.debug("Interface doesn't exist in config DS - no need to update parentRef, skipping");
598 WriteTransaction t = dataBroker.newWriteOnlyTransaction();
599 IfmUtil.updateInterfaceParentRef(t, interfaceName, parentInterfaceName);
600 CheckedFuture<Void, TransactionCommitFailedException> submitFuture = t.submit();
601 List<ListenableFuture<Void>> futures = new ArrayList<>();
602 futures.add(submitFuture);