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.CheckedFuture;
11 import com.google.common.util.concurrent.ListenableFuture;
12 import java.math.BigInteger;
13 import java.util.ArrayList;
14 import java.util.Collections;
15 import java.util.List;
17 import java.util.concurrent.Callable;
18 import java.util.concurrent.ConcurrentHashMap;
19 import java.util.concurrent.ExecutionException;
20 import java.util.concurrent.Future;
21 import javax.annotation.PostConstruct;
22 import javax.annotation.PreDestroy;
23 import javax.inject.Inject;
24 import javax.inject.Singleton;
25 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
26 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
27 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
28 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
29 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
30 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
31 import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
32 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
33 import org.opendaylight.genius.interfacemanager.commons.InterfaceManagerCommonUtils;
34 import org.opendaylight.genius.interfacemanager.commons.InterfaceMetaUtils;
35 import org.opendaylight.genius.interfacemanager.exceptions.InterfaceAlreadyExistsException;
36 import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo;
37 import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo.InterfaceAdminState;
38 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
39 import org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.BatchingUtils;
40 import org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.IfmClusterUtils;
41 import org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.SouthboundUtils;
42 import org.opendaylight.genius.interfacemanager.rpcservice.InterfaceManagerRpcService;
43 import org.opendaylight.genius.interfacemanager.servicebindings.flowbased.utilities.FlowBasedServicesUtils;
44 import org.opendaylight.genius.interfacemanager.statusanddiag.InterfaceStatusMonitor;
45 import org.opendaylight.genius.mdsalutil.ActionInfo;
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.idmanager.rev160406.CreateIdPoolInput;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInputBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info.InterfaceParentEntry;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info._interface.parent.entry.InterfaceChildEntry;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge._interface.info.BridgeEntry;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge._interface.info.bridge.entry.BridgeInterfaceEntry;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.dpn.to._interface.list.dpn.to._interface.InterfaceNameEntry;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfExternal;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfExternalBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlanBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefs;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefsBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEndpointIpForDpnInput;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEndpointIpForDpnInputBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEndpointIpForDpnOutput;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceInput;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceInputBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceOutput;
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.OvsdbBridgeAugmentation;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
86 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
87 import org.opendaylight.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 {
94 private static final Logger LOG = LoggerFactory.getLogger(InterfacemgrProvider.class);
95 private static final InterfaceStatusMonitor INTERFACE_STATUS_MONITOR = InterfaceStatusMonitor.getInstance();
96 private final DataBroker dataBroker;
97 private final IdManagerService idManager;
98 private final InterfaceManagerRpcService interfaceManagerRpcService;
99 private final EntityOwnershipService entityOwnershipService;
100 private Map<String, OvsdbTerminationPointAugmentation> ifaceToTpMap;
101 private Map<String, InstanceIdentifier<Node>> ifaceToNodeIidMap;
102 private Map<InstanceIdentifier<Node>, OvsdbBridgeAugmentation> nodeIidToBridgeMap;
105 public InterfacemgrProvider(final DataBroker dataBroker, final EntityOwnershipService entityOwnershipService,
106 final IdManagerService idManager, final InterfaceManagerRpcService interfaceManagerRpcService) {
107 this.dataBroker = dataBroker;
108 this.entityOwnershipService = entityOwnershipService;
109 this.idManager = idManager;
110 this.interfaceManagerRpcService = interfaceManagerRpcService;
114 @SuppressWarnings("checkstyle:IllegalCatch")
115 public void start() {
117 INTERFACE_STATUS_MONITOR.registerMbean();
119 IfmClusterUtils.registerEntityForOwnership(this, this.entityOwnershipService);
120 BatchingUtils.registerWithBatchManager(this.dataBroker);
121 this.ifaceToTpMap = new ConcurrentHashMap<>();
122 this.ifaceToNodeIidMap = new ConcurrentHashMap<>();
123 this.nodeIidToBridgeMap = new ConcurrentHashMap<>();
125 INTERFACE_STATUS_MONITOR.reportStatus("OPERATIONAL");
126 } catch (Exception e) {
127 INTERFACE_STATUS_MONITOR.reportStatus("ERROR");
130 LOG.info("InterfacemgrProvider Started");
135 public void close() throws Exception {
136 LOG.info("InterfacemgrProvider Closed");
139 public EntityOwnershipService getEntityOwnershipService() {
140 return entityOwnershipService;
143 public DataBroker getDataBroker() {
144 return this.dataBroker;
147 private void createIdPool() {
148 CreateIdPoolInput createPool = new CreateIdPoolInputBuilder().setPoolName(IfmConstants.IFM_IDPOOL_NAME)
149 .setLow(IfmConstants.IFM_ID_POOL_START).setHigh(IfmConstants.IFM_ID_POOL_END).build();
150 // TODO: Error handling
151 Future<RpcResult<Void>> result = idManager.createIdPool(createPool);
153 if (result != null && result.get().isSuccessful()) {
154 LOG.debug("Created IdPool for InterfaceMgr");
156 } catch (InterruptedException | ExecutionException e) {
157 LOG.error("Failed to create idPool for InterfaceMgr", e);
162 public Long getPortForInterface(String ifName) {
163 GetPortFromInterfaceInput input = new GetPortFromInterfaceInputBuilder().setIntfName(ifName).build();
164 Future<RpcResult<GetPortFromInterfaceOutput>> output = interfaceManagerRpcService.getPortFromInterface(input);
166 RpcResult<GetPortFromInterfaceOutput> port = output.get();
167 if (port.isSuccessful()) {
168 return port.getResult().getPortno();
170 } catch (NullPointerException | InterruptedException | ExecutionException e) {
171 LOG.warn("Exception when getting port for interface", e);
177 public Long getPortForInterface(Interface intf) {
178 GetPortFromInterfaceInput input = new GetPortFromInterfaceInputBuilder().setIntfName(intf.getName()).build();
179 Future<RpcResult<GetPortFromInterfaceOutput>> output = interfaceManagerRpcService.getPortFromInterface(input);
181 RpcResult<GetPortFromInterfaceOutput> port = output.get();
182 if (port.isSuccessful()) {
183 return port.getResult().getPortno();
185 } catch (NullPointerException | InterruptedException | ExecutionException e) {
186 LOG.warn("Exception when getting port for interface", e);
192 public InterfaceInfo getInterfaceInfo(String interfaceName) {
194 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
195 .ietf.interfaces.rev140508.interfaces.state.Interface ifState = InterfaceManagerCommonUtils
196 .getInterfaceState(interfaceName, dataBroker);
198 if (ifState == null) {
199 LOG.error("Interface {} is not present", interfaceName);
203 Interface intf = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(new InterfaceKey(interfaceName),
206 LOG.error("Interface {} doesn't exist in config datastore", interfaceName);
210 NodeConnectorId ncId = IfmUtil.getNodeConnectorIdFromInterface(intf.getName(), dataBroker);
211 InterfaceInfo.InterfaceType interfaceType = IfmUtil.getInterfaceType(intf);
212 InterfaceInfo interfaceInfo = new InterfaceInfo(interfaceName);
213 BigInteger dpId = org.opendaylight.genius.interfacemanager.globals.IfmConstants.INVALID_DPID;
214 Integer portNo = org.opendaylight.genius.interfacemanager.globals.IfmConstants.INVALID_PORT_NO;
216 dpId = IfmUtil.getDpnFromNodeConnectorId(ncId);
217 portNo = Integer.parseInt(IfmUtil.getPortNoFromNodeConnectorId(ncId));
219 if (interfaceType == InterfaceInfo.InterfaceType.VLAN_INTERFACE) {
220 interfaceInfo = IfmUtil.getVlanInterfaceInfo(interfaceName, intf, dpId);
221 } else if (interfaceType == InterfaceInfo.InterfaceType.UNKNOWN_INTERFACE) {
222 LOG.error("Type of Interface {} is unknown", interfaceName);
225 InterfaceInfo.InterfaceOpState opState;
226 if (ifState.getOperStatus() == OperStatus.Up) {
227 opState = InterfaceInfo.InterfaceOpState.UP;
228 } else if (ifState.getOperStatus() == OperStatus.Down) {
229 opState = InterfaceInfo.InterfaceOpState.DOWN;
231 opState = InterfaceInfo.InterfaceOpState.UNKNOWN;
233 interfaceInfo.setDpId(dpId);
234 interfaceInfo.setPortNo(portNo);
235 interfaceInfo.setAdminState(intf.isEnabled() ? InterfaceAdminState.ENABLED : InterfaceAdminState.DISABLED);
236 interfaceInfo.setInterfaceName(interfaceName);
237 Integer lportTag = ifState.getIfIndex();
238 interfaceInfo.setInterfaceTag(lportTag);
239 interfaceInfo.setInterfaceType(interfaceType);
240 interfaceInfo.setGroupId(IfmUtil.getGroupId(lportTag, interfaceType));
241 interfaceInfo.setOpState(opState);
242 PhysAddress phyAddress = ifState.getPhysAddress();
243 if (phyAddress != null) {
244 interfaceInfo.setMacAddress(ifState.getPhysAddress().getValue());
247 return interfaceInfo;
252 public InterfaceInfo getInterfaceInfoFromOperationalDataStore(String interfaceName,
253 InterfaceInfo.InterfaceType interfaceType) {
254 InterfaceInfo interfaceInfo = new InterfaceInfo(interfaceName);
255 org.opendaylight.yang.gen.v1.urn
256 .ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState =
257 InterfaceManagerCommonUtils
258 .getInterfaceState(interfaceName, dataBroker);
259 if (ifState == null) {
260 LOG.error("Interface {} is not present", interfaceName);
263 NodeConnectorId ncId = IfmUtil.getNodeConnectorIdFromInterface(ifState);
265 interfaceInfo.setDpId(IfmUtil.getDpnFromNodeConnectorId(ncId));
266 interfaceInfo.setPortNo(Integer.parseInt(IfmUtil.getPortNoFromNodeConnectorId(ncId)));
268 InterfaceInfo.InterfaceOpState opState;
269 if (ifState.getOperStatus() == OperStatus.Up) {
270 opState = InterfaceInfo.InterfaceOpState.UP;
271 } else if (ifState.getOperStatus() == OperStatus.Down) {
272 opState = InterfaceInfo.InterfaceOpState.DOWN;
274 opState = InterfaceInfo.InterfaceOpState.UNKNOWN;
276 interfaceInfo.setAdminState(ifState.getAdminStatus() == AdminStatus.Up ? InterfaceAdminState.ENABLED
277 : InterfaceAdminState.DISABLED);
278 interfaceInfo.setInterfaceName(interfaceName);
279 Integer lportTag = ifState.getIfIndex();
280 interfaceInfo.setInterfaceTag(lportTag);
281 interfaceInfo.setInterfaceType(interfaceType);
282 interfaceInfo.setGroupId(IfmUtil.getGroupId(lportTag, interfaceType));
283 interfaceInfo.setOpState(opState);
284 PhysAddress phyAddress = ifState.getPhysAddress();
285 if (phyAddress != null) {
286 interfaceInfo.setMacAddress(ifState.getPhysAddress().getValue());
288 return interfaceInfo;
292 public InterfaceInfo getInterfaceInfoFromOperationalDataStore(String interfaceName) {
293 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
294 .ietf.interfaces.rev140508.interfaces.state.Interface ifState = InterfaceManagerCommonUtils
295 .getInterfaceState(interfaceName, dataBroker);
296 if (ifState == null) {
297 LOG.error("Interface {} is not present", interfaceName);
301 return populateInterfaceInfo(interfaceName, ifState);
304 public InterfaceInfo populateInterfaceInfo(String interfaceName,
305 org.opendaylight.yang.gen.v1.urn
306 .ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState) {
307 InterfaceInfo interfaceInfo = new InterfaceInfo(interfaceName);
308 NodeConnectorId ncId = IfmUtil.getNodeConnectorIdFromInterface(ifState);
310 if (Tunnel.class.equals(ifState.getType())) {
311 interfaceInfo.setPortName(interfaceName);
313 Interface iface = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceName, dataBroker);
314 ParentRefs parentRefs = iface.getAugmentation(ParentRefs.class);
315 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 Interface intf = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(new InterfaceKey(interfaceName),
363 public void createVLANInterface(String interfaceName, String portName, BigInteger dpId, Integer vlanId,
364 String description, IfL2vlan.L2vlanMode l2vlanMode) throws InterfaceAlreadyExistsException {
365 createVLANInterface(interfaceName, portName, dpId, vlanId, description, l2vlanMode, false);
369 public void createVLANInterface(String interfaceName, String portName, BigInteger dpId, Integer vlanId,
370 String description, IfL2vlan.L2vlanMode l2vlanMode, boolean isExternal)
371 throws InterfaceAlreadyExistsException {
373 LOG.info("Create VLAN interface : {}", interfaceName);
374 Interface interfaceOptional = InterfaceManagerCommonUtils
375 .getInterfaceFromConfigDS(new InterfaceKey(interfaceName), dataBroker);
376 if (interfaceOptional != null) {
377 LOG.debug("VLAN interface is already exist", interfaceOptional.getDescription());
378 throw new InterfaceAlreadyExistsException(interfaceOptional.getName());
380 IfL2vlanBuilder l2vlanBuilder = new IfL2vlanBuilder().setL2vlanMode(l2vlanMode);
381 if (vlanId != null && vlanId > 0) {
382 l2vlanBuilder.setVlanId(new VlanId(vlanId));
384 ParentRefs parentRefs = new ParentRefsBuilder().setParentInterface(portName).build();
385 InterfaceBuilder interfaceBuilder = new InterfaceBuilder().setEnabled(true).setName(interfaceName)
386 .setType(L2vlan.class).addAugmentation(IfL2vlan.class, l2vlanBuilder.build())
387 .addAugmentation(ParentRefs.class, parentRefs).setDescription(description);
389 interfaceBuilder.addAugmentation(IfExternal.class, new IfExternalBuilder().setExternal(true).build());
391 InstanceIdentifier<Interface> interfaceInstanceIdentifier = InterfaceManagerCommonUtils
392 .getInterfaceIdentifier(new InterfaceKey(interfaceName));
393 WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
394 writeTransaction.put(LogicalDatastoreType.CONFIGURATION, interfaceInstanceIdentifier, interfaceBuilder.build(),
396 writeTransaction.submit();
399 private boolean isServiceBoundOnInterface(short servicePriority, String interfaceName,
400 Class<? extends ServiceModeBase> serviceMode) {
401 InstanceIdentifier<BoundServices> boundServicesIId = IfmUtil.buildBoundServicesIId(servicePriority,
402 interfaceName, serviceMode);
404 return SingleTransactionDataBroker
405 .syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION, boundServicesIId).isPresent();
406 } catch (ReadFailedException e) {
407 LOG.warn("Error while reading [{}]", boundServicesIId, e);
413 public boolean isServiceBoundOnInterfaceForIngress(short servicePriority, String interfaceName) {
414 return isServiceBoundOnInterface(servicePriority, interfaceName, ServiceModeIngress.class);
418 public boolean isServiceBoundOnInterfaceForEgress(short servicePriority, String interfaceName) {
419 return isServiceBoundOnInterface(servicePriority, interfaceName, ServiceModeEgress.class);
423 public void bindService(String interfaceName, Class<? extends ServiceModeBase> serviceMode,
424 BoundServices serviceInfo) {
425 bindService(interfaceName, serviceMode, serviceInfo, /* WriteTransaction */ null);
429 public void bindService(String interfaceName, Class<? extends ServiceModeBase> serviceMode,
430 BoundServices serviceInfo, WriteTransaction tx) {
431 WriteTransaction writeTransaction = tx != null ? tx : dataBroker.newWriteOnlyTransaction();
432 IfmUtil.bindService(writeTransaction, interfaceName, serviceInfo, serviceMode);
434 writeTransaction.submit();
439 public void unbindService(String interfaceName, Class<? extends ServiceModeBase> serviceMode,
440 BoundServices serviceInfo) {
441 IfmUtil.unbindService(dataBroker, interfaceName,
442 FlowBasedServicesUtils.buildServiceId(interfaceName, serviceInfo.getServicePriority(), serviceMode));
446 public BigInteger getDpnForInterface(Interface intrf) {
447 return getDpnForInterface(intrf.getName());
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 List<Interface> getVlanInterfaces() {
490 return InterfaceManagerCommonUtils.getAllVlanInterfacesFromCache();
494 public List<Interface> getVxlanInterfaces() {
495 return InterfaceManagerCommonUtils.getAllTunnelInterfacesFromCache();
499 public List<Interface> getChildInterfaces(String parentInterface) {
500 InterfaceParentEntry parentEntry = InterfaceMetaUtils.getInterfaceParentEntryFromConfigDS(parentInterface,
502 if (parentEntry == null) {
503 LOG.debug("No parent entry found for {}", parentInterface);
504 return Collections.emptyList();
507 List<InterfaceChildEntry> childEntries = parentEntry.getInterfaceChildEntry();
508 if (childEntries == null || childEntries.isEmpty()) {
509 LOG.debug("No child entries found for parent {}", parentInterface);
510 return Collections.emptyList();
513 List<Interface> childInterfaces = new ArrayList<>();
514 for (InterfaceChildEntry childEntry : childEntries) {
515 String interfaceName = childEntry.getChildInterface();
516 Interface iface = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceName, dataBroker);
518 childInterfaces.add(iface);
520 LOG.debug("Child interface {} not found in config DS for parent interface {}", interfaceName,
525 LOG.trace("Found child interfaces {} for parent {}", childInterfaces, parentInterface);
526 return childInterfaces;
530 public boolean isExternalInterface(String interfaceName) {
531 return isExternalInterface(getInterfaceInfoFromConfigDataStore(interfaceName));
534 private boolean isExternalInterface(Interface iface) {
539 IfExternal ifExternal = iface.getAugmentation(IfExternal.class);
540 return ifExternal != null && Boolean.TRUE.equals(ifExternal.isExternal());
544 public String getPortNameForInterface(NodeConnectorId nodeConnectorId, String interfaceName) {
545 return InterfaceManagerCommonUtils.getPortNameForInterface(nodeConnectorId, interfaceName);
549 public String getPortNameForInterface(String dpnId, String interfaceName) {
550 return InterfaceManagerCommonUtils.getPortNameForInterface(dpnId, interfaceName);
554 public Map<String, OvsdbTerminationPointAugmentation> getTerminationPointCache() {
555 return new ConcurrentHashMap<>(this.ifaceToTpMap);
558 public void addTerminationPointForInterface(String interfaceName,
559 OvsdbTerminationPointAugmentation terminationPoint) {
560 LOG.debug("Adding TerminationPoint {} to cache for Interface {}", terminationPoint.getName(), interfaceName);
561 if (interfaceName != null && terminationPoint != null) {
562 ifaceToTpMap.put(interfaceName, terminationPoint);
566 public OvsdbTerminationPointAugmentation getTerminationPoint(String interfaceName) {
567 return ifaceToTpMap.get(interfaceName);
570 public void removeTerminationPointForInterface(String interfaceName) {
571 LOG.debug("Removing TerminationPoint from cache for Interface {}", interfaceName);
572 if (interfaceName != null) {
573 ifaceToTpMap.remove(interfaceName);
577 public void addNodeIidForInterface(String interfaceName, InstanceIdentifier<Node> nodeIid) {
578 if (interfaceName != null && nodeIid != null) {
579 ifaceToNodeIidMap.put(interfaceName, nodeIid);
583 public void removeNodeIidForInterface(String interfaceName) {
584 if (interfaceName != null) {
585 ifaceToNodeIidMap.remove(interfaceName);
589 public InstanceIdentifier<Node> getNodeIidForInterface(String interfaceName) {
590 if (interfaceName != null) {
591 return ifaceToNodeIidMap.get(interfaceName);
596 private OvsdbBridgeAugmentation getBridgeForInterface(String interfaceName,
597 InstanceIdentifier<Node> nodeInstanceId) {
598 InstanceIdentifier<Node> nodeIid = nodeInstanceId;
599 if (nodeIid == null) {
600 nodeIid = getNodeIidForInterface(interfaceName);
602 return getBridgeForNodeIid(nodeIid);
605 public String getDpidForInterface(String interfaceName) {
606 return getDpidForInterface(interfaceName, null);
609 public String getDpidForInterface(String interfaceName, InstanceIdentifier<Node> nodeInstanceId) {
610 OvsdbBridgeAugmentation bridge = getBridgeForInterface(interfaceName, nodeInstanceId);
611 if (bridge != null) {
612 BigInteger dpid = IfmUtil.getDpnId(bridge.getDatapathId());
613 if (dpid != null && dpid.longValue() != 0) {
614 return String.valueOf(dpid);
620 public void addBridgeForNodeIid(InstanceIdentifier<Node> nodeIid, OvsdbBridgeAugmentation bridge) {
621 if (nodeIid != null && bridge != null) {
622 nodeIidToBridgeMap.put(nodeIid, bridge);
626 public void removeBridgeForNodeIid(InstanceIdentifier<Node> nodeIid) {
627 if (nodeIid != null) {
628 nodeIidToBridgeMap.remove(nodeIid);
632 public OvsdbBridgeAugmentation getBridgeForNodeIid(InstanceIdentifier<Node> nodeIid) {
633 if (nodeIid != null) {
634 return nodeIidToBridgeMap.get(nodeIid);
640 public String getParentRefNameForInterface(String interfaceName) {
641 String parentRefName = null;
643 String dpnId = getDpidForInterface(interfaceName, null);
644 OvsdbTerminationPointAugmentation ovsdbTp = getTerminationPoint(interfaceName);
645 if (ovsdbTp != null) {
647 LOG.error("Got NULL dpnId when looking for TP with external ID {}", interfaceName);
650 parentRefName = getPortNameForInterface(dpnId, ovsdbTp.getName());
651 LOG.debug("Building parent ref for interface {}, using parentRefName {} acquired by external ID",
652 interfaceName, parentRefName);
654 LOG.debug("Skipping parent ref for interface {}, as there is no termination point that references "
655 + "this interface yet.", interfaceName);
658 return parentRefName;
662 public void updateInterfaceParentRef(String interfaceName, String parentInterface) {
663 // This should generally be called by EOS Owner for
664 // INTERFACE_CONFIG_ENTITY - runOnlyInLeaderNode()
665 updateInterfaceParentRef(interfaceName, parentInterface, true);
669 public void updateInterfaceParentRef(String interfaceName, String parentInterface,
670 boolean readInterfaceBeforeWrite) {
671 // This should generally be called by EOS Owner for
672 // INTERFACE_CONFIG_ENTITY - runOnlyInLeaderNode()
673 if (interfaceName == null) {
677 DataStoreJobCoordinator jobCoordinator = DataStoreJobCoordinator.getInstance();
678 ParentRefUpdateWorker parentRefUpdateWorker = new ParentRefUpdateWorker(interfaceName, parentInterface,
679 readInterfaceBeforeWrite);
680 jobCoordinator.enqueueJob(interfaceName, parentRefUpdateWorker, IfmConstants.JOB_MAX_RETRIES);
683 public class ParentRefUpdateWorker implements Callable<List<ListenableFuture<Void>>> {
684 String interfaceName;
685 String parentInterfaceName;
686 Boolean readInterfaceBeforeWrite;
688 public ParentRefUpdateWorker(String interfaceName, String parentInterfaceName,
689 boolean readInterfaceBeforeWrite) {
690 this.interfaceName = interfaceName;
691 this.parentInterfaceName = parentInterfaceName;
692 this.readInterfaceBeforeWrite = readInterfaceBeforeWrite;
696 public List<ListenableFuture<Void>> call() throws Exception {
697 if (readInterfaceBeforeWrite) {
698 Interface iface = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceName, dataBroker);
700 LOG.debug("Interface doesn't exist in config DS - no need to update parentRef, skipping");
704 WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
705 IfmUtil.updateInterfaceParentRef(writeTransaction, interfaceName, parentInterfaceName);
706 CheckedFuture<Void, TransactionCommitFailedException> submitFuture = writeTransaction.submit();
707 List<ListenableFuture<Void>> futures = new ArrayList<>();
708 futures.add(submitFuture);
714 public OvsdbTerminationPointAugmentation getTerminationPointForInterface(String interfaceName) {
715 return getTerminationPoint(interfaceName);
719 public OvsdbBridgeAugmentation getOvsdbBridgeForInterface(String interfaceName) {
720 return getBridgeForInterface(interfaceName, null);
724 public OvsdbBridgeAugmentation getOvsdbBridgeForNodeIid(InstanceIdentifier<Node> nodeIid) {
725 return getBridgeForNodeIid(nodeIid);
730 * Get all termination points on a given DPN.
731 * This API conflicts with getTunnelPortsOnBridge since both read from two different DS,
732 * probable future optimization will be to make both of them use the same DS.
736 * Datapath Node Identifier
738 * @return If the data at the supplied path exists, returns a list of all termination point
741 public List<OvsdbTerminationPointAugmentation> getPortsOnBridge(BigInteger dpnId) {
742 List<OvsdbTerminationPointAugmentation> tpList = null;
743 List<InterfaceNameEntry> interfaceList = InterfaceManagerCommonUtils.getAllInterfaces(dpnId, dataBroker);
744 if (interfaceList != null) {
745 tpList = new ArrayList<>();
746 for (InterfaceNameEntry ifaceEntry: interfaceList) {
747 OvsdbTerminationPointAugmentation terminationPoint =
748 getTerminationPointForInterface(ifaceEntry.getInterfaceName());
749 LOG.trace("Found TerminationPoint {} for interface {}", terminationPoint,
750 ifaceEntry.getInterfaceName());
751 if (terminationPoint != null) {
752 tpList.add(terminationPoint);
760 public List<OvsdbTerminationPointAugmentation> getTunnelPortsOnBridge(BigInteger dpnId) {
761 List<OvsdbTerminationPointAugmentation> tpList = null;
762 BridgeEntry bridgeEntry = InterfaceMetaUtils.getBridgeEntryFromConfigDS(dpnId, dataBroker);
763 if (bridgeEntry != null) {
764 tpList = new ArrayList<>();
765 for (BridgeInterfaceEntry ifaceEntry: bridgeEntry.getBridgeInterfaceEntry()) {
766 OvsdbTerminationPointAugmentation terminationPoint =
767 getTerminationPointForInterface(ifaceEntry.getInterfaceName());
768 LOG.trace("Found TerminationPoint {} for interface {}", terminationPoint,
769 ifaceEntry.getInterfaceName());
770 if (terminationPoint != null
771 && SouthboundUtils.isInterfaceTypeTunnel(terminationPoint.getInterfaceType())) {
772 tpList.add(terminationPoint);
779 public long getLogicalTunnelSelectGroupId(int lportTag) {
780 return IfmUtil.getLogicalTunnelSelectGroupId(lportTag);