2 * Copyright (c) 2016, 2017 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.genius.interfacemanager;
10 import static org.opendaylight.controller.md.sal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
11 import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.CONFIGURATION;
13 import com.google.common.util.concurrent.ListenableFuture;
14 import java.math.BigInteger;
15 import java.util.ArrayList;
16 import java.util.Collections;
17 import java.util.List;
19 import java.util.concurrent.Callable;
20 import java.util.concurrent.ConcurrentHashMap;
21 import java.util.concurrent.ExecutionException;
22 import java.util.concurrent.Future;
23 import javax.annotation.PostConstruct;
24 import javax.annotation.PreDestroy;
25 import javax.inject.Inject;
26 import javax.inject.Singleton;
27 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
28 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
29 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
30 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
31 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
32 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
33 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
34 import org.opendaylight.genius.interfacemanager.commons.InterfaceManagerCommonUtils;
35 import org.opendaylight.genius.interfacemanager.commons.InterfaceMetaUtils;
36 import org.opendaylight.genius.interfacemanager.exceptions.InterfaceAlreadyExistsException;
37 import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo;
38 import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo.InterfaceAdminState;
39 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
40 import org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.SouthboundUtils;
41 import org.opendaylight.genius.interfacemanager.rpcservice.InterfaceManagerRpcService;
42 import org.opendaylight.genius.interfacemanager.servicebindings.flowbased.utilities.FlowBasedServicesUtils;
43 import org.opendaylight.genius.mdsalutil.ActionInfo;
44 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
45 import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
46 import org.opendaylight.mdsal.eos.binding.api.Entity;
47 import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipCandidateRegistration;
48 import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipService;
49 import org.opendaylight.mdsal.eos.common.api.CandidateAlreadyRegisteredException;
50 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan;
51 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel;
52 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
53 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
54 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
55 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
56 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus;
57 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus;
58 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
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.config.rev160406.IfmConfig;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info.InterfaceParentEntry;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info._interface.parent.entry.InterfaceChildEntry;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfExternal;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfExternalBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlanBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefs;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefsBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEndpointIpForDpnInput;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEndpointIpForDpnInputBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEndpointIpForDpnOutput;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceInput;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceInputBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceOutput;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeBase;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeEgress;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeIngress;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServices;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeBase;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
89 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
90 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
91 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
92 import org.opendaylight.yangtools.yang.common.RpcResult;
93 import org.slf4j.Logger;
94 import org.slf4j.LoggerFactory;
97 public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
98 private static final Logger LOG = LoggerFactory.getLogger(InterfacemgrProvider.class);
100 private final DataBroker dataBroker;
101 private final ManagedNewTransactionRunner txRunner;
102 private final IdManagerService idManager;
103 private final InterfaceManagerRpcService interfaceManagerRpcService;
104 private final EntityOwnershipService entityOwnershipService;
105 private final JobCoordinator coordinator;
106 private final InterfaceManagerCommonUtils interfaceManagerCommonUtils;
107 private final InterfaceMetaUtils interfaceMetaUtils;
108 private final IfmConfig ifmConfig;
109 private Map<String, OvsdbTerminationPointAugmentation> ifaceToTpMap;
110 private Map<String, InstanceIdentifier<Node>> ifaceToNodeIidMap;
111 private Map<InstanceIdentifier<Node>, OvsdbBridgeAugmentation> nodeIidToBridgeMap;
112 private EntityOwnershipCandidateRegistration configEntityCandidate;
113 private EntityOwnershipCandidateRegistration bindingEntityCandidate;
116 public InterfacemgrProvider(final DataBroker dataBroker, final EntityOwnershipService entityOwnershipService,
117 final IdManagerService idManager, final InterfaceManagerRpcService interfaceManagerRpcService,
118 final JobCoordinator coordinator, final InterfaceManagerCommonUtils interfaceManagerCommonUtils,
119 final InterfaceMetaUtils interfaceMetaUtils, final IfmConfig ifmConfig) {
120 this.dataBroker = dataBroker;
121 this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
122 this.entityOwnershipService = entityOwnershipService;
123 this.idManager = idManager;
124 this.interfaceManagerRpcService = interfaceManagerRpcService;
125 this.coordinator = coordinator;
126 this.interfaceManagerCommonUtils = interfaceManagerCommonUtils;
127 this.interfaceMetaUtils = interfaceMetaUtils;
128 this.ifmConfig = ifmConfig;
132 @SuppressWarnings("checkstyle:IllegalCatch")
133 public void start() {
136 configEntityCandidate = entityOwnershipService.registerCandidate(
137 new Entity(IfmConstants.INTERFACE_CONFIG_ENTITY, IfmConstants.INTERFACE_CONFIG_ENTITY));
138 bindingEntityCandidate = entityOwnershipService.registerCandidate(
139 new Entity(IfmConstants.INTERFACE_SERVICE_BINDING_ENTITY,
140 IfmConstants.INTERFACE_SERVICE_BINDING_ENTITY));
141 } catch (CandidateAlreadyRegisteredException e) {
142 LOG.error("Failed to register entity {} with EntityOwnershipService", e.getEntity());
145 this.ifaceToTpMap = new ConcurrentHashMap<>();
146 this.ifaceToNodeIidMap = new ConcurrentHashMap<>();
147 this.nodeIidToBridgeMap = new ConcurrentHashMap<>();
148 LOG.info("InterfacemgrProvider Started");
153 public void close() throws Exception {
154 if (configEntityCandidate != null) {
155 configEntityCandidate.close();
158 if (bindingEntityCandidate != null) {
159 bindingEntityCandidate.close();
162 LOG.info("InterfacemgrProvider Closed");
165 public EntityOwnershipService getEntityOwnershipService() {
166 return entityOwnershipService;
169 public DataBroker getDataBroker() {
170 return this.dataBroker;
173 private void createIdPool() {
174 CreateIdPoolInput createPool = new CreateIdPoolInputBuilder().setPoolName(IfmConstants.IFM_IDPOOL_NAME)
175 .setLow(IfmConstants.IFM_ID_POOL_START).setHigh(IfmConstants.IFM_ID_POOL_END).build();
176 // TODO: Error handling
177 Future<RpcResult<Void>> result = idManager.createIdPool(createPool);
179 if (result != null && result.get().isSuccessful()) {
180 LOG.debug("Created IdPool for InterfaceMgr");
182 } catch (InterruptedException | ExecutionException e) {
183 LOG.error("Failed to create idPool for InterfaceMgr", e);
188 public Long getPortForInterface(String ifName) {
189 GetPortFromInterfaceInput input = new GetPortFromInterfaceInputBuilder().setIntfName(ifName).build();
190 Future<RpcResult<GetPortFromInterfaceOutput>> output = interfaceManagerRpcService.getPortFromInterface(input);
192 RpcResult<GetPortFromInterfaceOutput> port = output.get();
193 if (port.isSuccessful()) {
194 return port.getResult().getPortno();
196 } catch (NullPointerException | InterruptedException | ExecutionException e) {
197 LOG.warn("Exception when getting port for interface", e);
203 public Long getPortForInterface(Interface intf) {
204 GetPortFromInterfaceInput input = new GetPortFromInterfaceInputBuilder().setIntfName(intf.getName()).build();
205 Future<RpcResult<GetPortFromInterfaceOutput>> output = interfaceManagerRpcService.getPortFromInterface(input);
207 RpcResult<GetPortFromInterfaceOutput> port = output.get();
208 if (port.isSuccessful()) {
209 return port.getResult().getPortno();
211 } catch (NullPointerException | InterruptedException | ExecutionException e) {
212 LOG.warn("Exception when getting port for interface", e);
218 public InterfaceInfo getInterfaceInfo(String interfaceName) {
220 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
221 .ietf.interfaces.rev140508.interfaces.state.Interface ifState = interfaceManagerCommonUtils
222 .getInterfaceState(interfaceName);
224 if (ifState == null) {
225 LOG.debug("Interface {} is not present", interfaceName);
229 Interface intf = interfaceManagerCommonUtils.getInterfaceFromConfigDS(new InterfaceKey(interfaceName));
231 LOG.error("Interface {} doesn't exist in config datastore", interfaceName);
235 NodeConnectorId ncId = FlowBasedServicesUtils.getNodeConnectorIdFromInterface(intf.getName(),
236 interfaceManagerCommonUtils);
237 InterfaceInfo.InterfaceType interfaceType = IfmUtil.getInterfaceType(intf);
238 InterfaceInfo interfaceInfo = new InterfaceInfo(interfaceName);
239 BigInteger dpId = org.opendaylight.genius.interfacemanager.globals.IfmConstants.INVALID_DPID;
240 Integer portNo = org.opendaylight.genius.interfacemanager.globals.IfmConstants.INVALID_PORT_NO;
242 dpId = IfmUtil.getDpnFromNodeConnectorId(ncId);
243 portNo = Integer.parseInt(IfmUtil.getPortNoFromNodeConnectorId(ncId));
245 if (interfaceType == InterfaceInfo.InterfaceType.VLAN_INTERFACE) {
246 interfaceInfo = IfmUtil.getVlanInterfaceInfo(intf, dpId);
247 } else if (interfaceType == InterfaceInfo.InterfaceType.UNKNOWN_INTERFACE) {
248 LOG.error("Type of Interface {} is unknown", interfaceName);
251 InterfaceInfo.InterfaceOpState opState;
252 if (ifState.getOperStatus() == OperStatus.Up) {
253 opState = InterfaceInfo.InterfaceOpState.UP;
254 } else if (ifState.getOperStatus() == OperStatus.Down) {
255 opState = InterfaceInfo.InterfaceOpState.DOWN;
257 opState = InterfaceInfo.InterfaceOpState.UNKNOWN;
259 interfaceInfo.setDpId(dpId);
260 interfaceInfo.setPortNo(portNo);
261 interfaceInfo.setAdminState(intf.isEnabled() ? InterfaceAdminState.ENABLED : InterfaceAdminState.DISABLED);
262 interfaceInfo.setInterfaceName(interfaceName);
263 Integer lportTag = ifState.getIfIndex();
264 interfaceInfo.setInterfaceTag(lportTag);
265 interfaceInfo.setInterfaceType(interfaceType);
266 interfaceInfo.setGroupId(IfmUtil.getGroupId(lportTag, interfaceType));
267 interfaceInfo.setOpState(opState);
268 PhysAddress phyAddress = ifState.getPhysAddress();
269 if (phyAddress != null) {
270 interfaceInfo.setMacAddress(ifState.getPhysAddress().getValue());
273 return interfaceInfo;
278 public InterfaceInfo getInterfaceInfoFromOperationalDataStore(String interfaceName,
279 InterfaceInfo.InterfaceType interfaceType) {
280 InterfaceInfo interfaceInfo = new InterfaceInfo(interfaceName);
281 org.opendaylight.yang.gen.v1.urn
282 .ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState =
283 interfaceManagerCommonUtils.getInterfaceState(interfaceName);
284 if (ifState == null) {
285 LOG.debug("Interface {} is not present", interfaceName);
288 NodeConnectorId ncId = IfmUtil.getNodeConnectorIdFromInterface(ifState);
290 interfaceInfo.setDpId(IfmUtil.getDpnFromNodeConnectorId(ncId));
291 interfaceInfo.setPortNo(Integer.parseInt(IfmUtil.getPortNoFromNodeConnectorId(ncId)));
293 InterfaceInfo.InterfaceOpState opState;
294 if (ifState.getOperStatus() == OperStatus.Up) {
295 opState = InterfaceInfo.InterfaceOpState.UP;
296 } else if (ifState.getOperStatus() == OperStatus.Down) {
297 opState = InterfaceInfo.InterfaceOpState.DOWN;
299 opState = InterfaceInfo.InterfaceOpState.UNKNOWN;
301 interfaceInfo.setAdminState(ifState.getAdminStatus() == AdminStatus.Up ? InterfaceAdminState.ENABLED
302 : InterfaceAdminState.DISABLED);
303 interfaceInfo.setInterfaceName(interfaceName);
304 Integer lportTag = ifState.getIfIndex();
305 interfaceInfo.setInterfaceTag(lportTag);
306 interfaceInfo.setInterfaceType(interfaceType);
307 interfaceInfo.setGroupId(IfmUtil.getGroupId(lportTag, interfaceType));
308 interfaceInfo.setOpState(opState);
309 PhysAddress phyAddress = ifState.getPhysAddress();
310 if (phyAddress != null) {
311 interfaceInfo.setMacAddress(ifState.getPhysAddress().getValue());
313 return interfaceInfo;
317 public InterfaceInfo getInterfaceInfoFromOperationalDataStore(String interfaceName) {
318 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
319 .ietf.interfaces.rev140508.interfaces.state.Interface ifState = interfaceManagerCommonUtils
320 .getInterfaceState(interfaceName);
321 if (ifState == null) {
322 LOG.debug("Interface {} is not present", interfaceName);
326 return populateInterfaceInfo(interfaceName, ifState);
329 public InterfaceInfo populateInterfaceInfo(String interfaceName,
330 org.opendaylight.yang.gen.v1.urn
331 .ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState) {
332 InterfaceInfo interfaceInfo = new InterfaceInfo(interfaceName);
333 NodeConnectorId ncId = IfmUtil.getNodeConnectorIdFromInterface(ifState);
335 if (Tunnel.class.equals(ifState.getType())) {
336 interfaceInfo.setPortName(interfaceName);
338 Interface iface = interfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceName);
340 ParentRefs parentRefs = iface.getAugmentation(ParentRefs.class);
341 interfaceInfo.setPortName(parentRefs.getParentInterface());
344 interfaceInfo.setDpId(IfmUtil.getDpnFromNodeConnectorId(ncId));
345 interfaceInfo.setPortNo(Integer.parseInt(IfmUtil.getPortNoFromNodeConnectorId(ncId)));
347 InterfaceInfo.InterfaceOpState opState;
348 if (ifState.getOperStatus() == OperStatus.Up) {
349 opState = InterfaceInfo.InterfaceOpState.UP;
350 } else if (ifState.getOperStatus() == OperStatus.Down) {
351 opState = InterfaceInfo.InterfaceOpState.DOWN;
353 opState = InterfaceInfo.InterfaceOpState.UNKNOWN;
355 interfaceInfo.setAdminState(ifState.getAdminStatus() == AdminStatus.Up ? InterfaceAdminState.ENABLED
356 : InterfaceAdminState.DISABLED);
357 interfaceInfo.setInterfaceName(interfaceName);
358 Integer lportTag = ifState.getIfIndex();
359 if (lportTag != null) {
360 interfaceInfo.setInterfaceTag(lportTag);
362 interfaceInfo.setOpState(opState);
363 PhysAddress phyAddress = ifState.getPhysAddress();
364 if (phyAddress != null) {
365 interfaceInfo.setMacAddress(ifState.getPhysAddress().getValue());
367 return interfaceInfo;
371 public InterfaceInfo getInterfaceInfoFromOperationalDSCache(String interfaceName) {
372 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
373 .ietf.interfaces.rev140508.interfaces.state.Interface ifState = interfaceManagerCommonUtils
374 .getInterfaceStateFromCache(interfaceName);
375 if (ifState == null) {
376 LOG.warn("Interface {} is not present", interfaceName);
379 return populateInterfaceInfo(interfaceName, ifState);
383 public Interface getInterfaceInfoFromConfigDataStore(String interfaceName) {
384 return interfaceManagerCommonUtils.getInterfaceFromConfigDS(new InterfaceKey(interfaceName));
388 public void createVLANInterface(String interfaceName, String portName, BigInteger dpId, Integer vlanId,
389 String description, IfL2vlan.L2vlanMode l2vlanMode) throws InterfaceAlreadyExistsException {
390 createVLANInterface(interfaceName, portName, vlanId, description, l2vlanMode);
394 public void createVLANInterface(String interfaceName, String portName, Integer vlanId,
395 String description, IfL2vlan.L2vlanMode l2vlanMode) throws InterfaceAlreadyExistsException {
396 createVLANInterface(interfaceName, portName, vlanId, description, l2vlanMode, false);
400 public void createVLANInterface(String interfaceName, String portName, BigInteger dpId, Integer vlanId,
401 String description, IfL2vlan.L2vlanMode l2vlanMode, boolean isExternal)
402 throws InterfaceAlreadyExistsException {
403 createVLANInterface(interfaceName, portName, vlanId, description, l2vlanMode, isExternal);
407 public void createVLANInterface(String interfaceName, String portName, Integer vlanId,
408 String description, IfL2vlan.L2vlanMode l2vlanMode, boolean isExternal)
409 throws InterfaceAlreadyExistsException {
411 LOG.info("Create VLAN interface : {}", interfaceName);
412 Interface interfaceOptional = interfaceManagerCommonUtils
413 .getInterfaceFromConfigDS(new InterfaceKey(interfaceName));
414 if (interfaceOptional != null) {
415 LOG.debug("VLAN interface already exists {} ", interfaceOptional.getDescription());
416 throw new InterfaceAlreadyExistsException(interfaceOptional.getName());
418 IfL2vlanBuilder l2vlanBuilder = new IfL2vlanBuilder().setL2vlanMode(l2vlanMode);
419 if (vlanId != null && vlanId > 0) {
420 l2vlanBuilder.setVlanId(new VlanId(vlanId));
422 ParentRefs parentRefs = new ParentRefsBuilder().setParentInterface(portName).build();
423 InterfaceBuilder interfaceBuilder = new InterfaceBuilder().setEnabled(true).setName(interfaceName)
424 .setType(L2vlan.class).addAugmentation(IfL2vlan.class, l2vlanBuilder.build())
425 .addAugmentation(ParentRefs.class, parentRefs).setDescription(description);
427 interfaceBuilder.addAugmentation(IfExternal.class, new IfExternalBuilder().setExternal(true).build());
429 InstanceIdentifier<Interface> interfaceIId = interfaceManagerCommonUtils
430 .getInterfaceIdentifier(new InterfaceKey(interfaceName));
431 ListenableFutures.addErrorLogging(
432 txRunner.callWithNewWriteOnlyTransactionAndSubmit(
433 tx -> tx.put(CONFIGURATION, interfaceIId, interfaceBuilder.build(), CREATE_MISSING_PARENTS)),
434 LOG, "Failed to (async) write {}", interfaceIId);
437 private boolean isServiceBoundOnInterface(short servicePriority, String interfaceName,
438 Class<? extends ServiceModeBase> serviceMode) {
439 InstanceIdentifier<BoundServices> boundServicesIId = IfmUtil.buildBoundServicesIId(servicePriority,
440 interfaceName, serviceMode);
442 return SingleTransactionDataBroker
443 .syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION, boundServicesIId).isPresent();
444 } catch (ReadFailedException e) {
445 LOG.warn("Error while reading [{}]", boundServicesIId, e);
451 public boolean isServiceBoundOnInterfaceForIngress(short servicePriority, String interfaceName) {
452 return isServiceBoundOnInterface(servicePriority, interfaceName, ServiceModeIngress.class);
456 public boolean isServiceBoundOnInterfaceForEgress(short servicePriority, String interfaceName) {
457 return isServiceBoundOnInterface(servicePriority, interfaceName, ServiceModeEgress.class);
461 public void bindService(String interfaceName, Class<? extends ServiceModeBase> serviceMode,
462 BoundServices serviceInfo) {
463 bindService(interfaceName, serviceMode, serviceInfo, /* WriteTransaction */ null);
467 public void bindService(String interfaceName, Class<? extends ServiceModeBase> serviceMode,
468 BoundServices serviceInfo, WriteTransaction tx) {
470 ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(
471 wtx -> IfmUtil.bindService(wtx, interfaceName, serviceInfo, serviceMode)), LOG,
472 "Error binding the InterfacemgrProvider service");
474 IfmUtil.bindService(tx, interfaceName, serviceInfo, serviceMode);
479 public void unbindService(String interfaceName, Class<? extends ServiceModeBase> serviceMode,
480 BoundServices serviceInfo) {
481 IfmUtil.unbindService(txRunner, coordinator, interfaceName,
482 FlowBasedServicesUtils.buildServiceId(interfaceName, serviceInfo.getServicePriority(), serviceMode));
486 public BigInteger getDpnForInterface(Interface intrf) {
487 return getDpnForInterface(intrf.getName());
491 public BigInteger getDpnForInterface(String ifName) {
492 GetDpidFromInterfaceInput input = new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
493 Future<RpcResult<GetDpidFromInterfaceOutput>> output = interfaceManagerRpcService.getDpidFromInterface(input);
495 RpcResult<GetDpidFromInterfaceOutput> dpn = output.get();
496 if (dpn.isSuccessful()) {
497 return dpn.getResult().getDpid();
499 } catch (NullPointerException | InterruptedException | ExecutionException e) {
500 LOG.warn("Exception when getting port for interface", e);
506 public String getEndpointIpForDpn(BigInteger dpnId) {
507 GetEndpointIpForDpnInput input = new GetEndpointIpForDpnInputBuilder().setDpid(dpnId).build();
508 Future<RpcResult<GetEndpointIpForDpnOutput>> output = interfaceManagerRpcService.getEndpointIpForDpn(input);
510 RpcResult<GetEndpointIpForDpnOutput> ipForDpnOutputRpcResult = output.get();
511 if (ipForDpnOutputRpcResult.isSuccessful()) {
512 List<IpAddress> localIps = ipForDpnOutputRpcResult.getResult().getLocalIps();
513 if (!localIps.isEmpty()) {
514 return localIps.get(0).getIpv4Address().getValue();
517 } catch (NullPointerException | InterruptedException | ExecutionException e) {
518 LOG.warn("Exception when getting port for interface", e);
524 public List<ActionInfo> getInterfaceEgressActions(String ifName) {
525 return IfmUtil.getEgressActionInfosForInterface(ifName, 0, interfaceManagerCommonUtils, false);
529 public List<Interface> getVlanInterfaces() {
530 return interfaceManagerCommonUtils.getAllVlanInterfacesFromCache();
534 public List<Interface> getVxlanInterfaces() {
535 return interfaceManagerCommonUtils.getAllTunnelInterfacesFromCache();
539 public List<Interface> getChildInterfaces(String parentInterface) {
540 InterfaceParentEntry parentEntry = interfaceMetaUtils.getInterfaceParentEntryFromConfigDS(parentInterface);
541 if (parentEntry == null) {
542 LOG.debug("No parent entry found for {}", parentInterface);
543 return Collections.emptyList();
546 List<InterfaceChildEntry> childEntries = parentEntry.getInterfaceChildEntry();
547 if (childEntries == null || childEntries.isEmpty()) {
548 LOG.debug("No child entries found for parent {}", parentInterface);
549 return Collections.emptyList();
552 List<Interface> childInterfaces = new ArrayList<>();
553 for (InterfaceChildEntry childEntry : childEntries) {
554 String interfaceName = childEntry.getChildInterface();
555 Interface iface = interfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceName);
557 childInterfaces.add(iface);
559 LOG.debug("Child interface {} not found in config DS for parent interface {}", interfaceName,
564 LOG.trace("Found child interfaces {} for parent {}", childInterfaces, parentInterface);
565 return childInterfaces;
569 public boolean isExternalInterface(String interfaceName) {
570 return isExternalInterface(getInterfaceInfoFromConfigDataStore(interfaceName));
573 private boolean isExternalInterface(Interface iface) {
578 IfExternal ifExternal = iface.getAugmentation(IfExternal.class);
579 return ifExternal != null && Boolean.TRUE.equals(ifExternal.isExternal());
583 public String getPortNameForInterface(NodeConnectorId nodeConnectorId, String interfaceName) {
584 return InterfaceManagerCommonUtils.getPortNameForInterface(nodeConnectorId, interfaceName);
588 public String getPortNameForInterface(String dpnId, String interfaceName) {
589 return InterfaceManagerCommonUtils.getPortNameForInterface(dpnId, interfaceName);
593 public Map<String, OvsdbTerminationPointAugmentation> getTerminationPointCache() {
594 return new ConcurrentHashMap<>(this.ifaceToTpMap);
598 public Map<String, OperStatus> getBfdStateCache() {
599 return interfaceManagerCommonUtils.getBfdStateMap();
602 public void addTerminationPointForInterface(String interfaceName,
603 OvsdbTerminationPointAugmentation terminationPoint) {
604 if (interfaceName != null && terminationPoint != null) {
605 LOG.debug("Adding TerminationPoint {} to cache for Interface {}", terminationPoint.getName(),
607 ifaceToTpMap.put(interfaceName, terminationPoint);
611 public OvsdbTerminationPointAugmentation getTerminationPoint(String interfaceName) {
612 return ifaceToTpMap.get(interfaceName);
615 public void removeTerminationPointForInterface(String interfaceName) {
616 LOG.debug("Removing TerminationPoint from cache for Interface {}", interfaceName);
617 if (interfaceName != null) {
618 ifaceToTpMap.remove(interfaceName);
622 public void addNodeIidForInterface(String interfaceName, InstanceIdentifier<Node> nodeIid) {
623 if (interfaceName != null && nodeIid != null) {
624 ifaceToNodeIidMap.put(interfaceName, nodeIid);
628 public void removeNodeIidForInterface(String interfaceName) {
629 if (interfaceName != null) {
630 ifaceToNodeIidMap.remove(interfaceName);
634 public InstanceIdentifier<Node> getNodeIidForInterface(String interfaceName) {
635 if (interfaceName != null) {
636 return ifaceToNodeIidMap.get(interfaceName);
641 private OvsdbBridgeAugmentation getBridgeForInterface(String interfaceName,
642 InstanceIdentifier<Node> nodeInstanceId) {
643 InstanceIdentifier<Node> nodeIid = nodeInstanceId;
644 if (nodeIid == null) {
645 nodeIid = getNodeIidForInterface(interfaceName);
647 return getBridgeForNodeIid(nodeIid);
650 public String getDpidForInterface(String interfaceName) {
651 return getDpidForInterface(interfaceName, null);
654 public String getDpidForInterface(String interfaceName, InstanceIdentifier<Node> nodeInstanceId) {
655 OvsdbBridgeAugmentation bridge = getBridgeForInterface(interfaceName, nodeInstanceId);
656 if (bridge != null) {
657 BigInteger dpid = IfmUtil.getDpnId(bridge.getDatapathId());
658 if (dpid != null && dpid.longValue() != 0) {
659 return String.valueOf(dpid);
665 public void addBridgeForNodeIid(InstanceIdentifier<Node> nodeIid, OvsdbBridgeAugmentation bridge) {
666 if (nodeIid != null && bridge != null) {
667 nodeIidToBridgeMap.put(nodeIid, bridge);
671 public void removeBridgeForNodeIid(InstanceIdentifier<Node> nodeIid) {
672 if (nodeIid != null) {
673 nodeIidToBridgeMap.remove(nodeIid);
677 public OvsdbBridgeAugmentation getBridgeForNodeIid(InstanceIdentifier<Node> nodeIid) {
678 if (nodeIid == null) {
682 OvsdbBridgeAugmentation ret = nodeIidToBridgeMap.get(nodeIid);
687 LOG.info("Node {} not found in cache, reading from md-sal", nodeIid);
690 node = SingleTransactionDataBroker.syncRead(
691 dataBroker, LogicalDatastoreType.OPERATIONAL, nodeIid);
692 } catch (ReadFailedException e) {
693 LOG.error("Failed to read Node for {} ", nodeIid, e);
697 OvsdbBridgeAugmentation bridge = node.getAugmentation(OvsdbBridgeAugmentation.class);
698 if (bridge == null) {
699 LOG.error("Node {} has no bridge augmentation");
703 addBridgeForNodeIid(nodeIid, bridge);
708 public String getParentRefNameForInterface(String interfaceName) {
709 String parentRefName = null;
711 String dpnId = getDpidForInterface(interfaceName, null);
712 OvsdbTerminationPointAugmentation ovsdbTp = getTerminationPoint(interfaceName);
713 if (ovsdbTp != null) {
715 LOG.error("Got NULL dpnId when looking for TP with external ID {}", interfaceName);
718 parentRefName = getPortNameForInterface(dpnId, ovsdbTp.getName());
719 LOG.debug("Building parent ref for interface {}, using parentRefName {} acquired by external ID",
720 interfaceName, parentRefName);
722 LOG.debug("Skipping parent ref for interface {}, as there is no termination point that references "
723 + "this interface yet.", interfaceName);
726 return parentRefName;
730 public void updateInterfaceParentRef(String interfaceName, String parentInterface) {
731 // This should generally be called by EOS Owner for
732 // INTERFACE_CONFIG_ENTITY - runOnlyInLeaderNode()
733 updateInterfaceParentRef(interfaceName, parentInterface, true);
737 public void updateInterfaceParentRef(String interfaceName, String parentInterface,
738 boolean readInterfaceBeforeWrite) {
739 // This should generally be called by EOS Owner for
740 // INTERFACE_CONFIG_ENTITY - runOnlyInLeaderNode()
741 if (interfaceName == null) {
745 ParentRefUpdateWorker parentRefUpdateWorker = new ParentRefUpdateWorker(interfaceName, parentInterface,
746 readInterfaceBeforeWrite);
747 coordinator.enqueueJob(interfaceName, parentRefUpdateWorker, IfmConstants.JOB_MAX_RETRIES);
750 public class ParentRefUpdateWorker implements Callable<List<ListenableFuture<Void>>> {
751 String interfaceName;
752 String parentInterfaceName;
753 Boolean readInterfaceBeforeWrite;
755 public ParentRefUpdateWorker(String interfaceName, String parentInterfaceName,
756 boolean readInterfaceBeforeWrite) {
757 this.interfaceName = interfaceName;
758 this.parentInterfaceName = parentInterfaceName;
759 this.readInterfaceBeforeWrite = readInterfaceBeforeWrite;
763 public List<ListenableFuture<Void>> call() throws Exception {
764 if (readInterfaceBeforeWrite) {
765 Interface iface = interfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceName);
767 LOG.debug("Interface doesn't exist in config DS - no need to update parentRef, skipping");
771 return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(
772 tx -> IfmUtil.updateInterfaceParentRef(tx, interfaceName, parentInterfaceName)));
777 public OvsdbTerminationPointAugmentation getTerminationPointForInterface(String interfaceName) {
778 return getTerminationPoint(interfaceName);
782 public OvsdbBridgeAugmentation getOvsdbBridgeForInterface(String interfaceName) {
783 return getBridgeForInterface(interfaceName, null);
787 public OvsdbBridgeAugmentation getOvsdbBridgeForNodeIid(InstanceIdentifier<Node> nodeIid) {
788 return getBridgeForNodeIid(nodeIid);
793 * Get all termination points on a given DPN.
794 * This API uses read on Operational DS. If there are perf issues in cluster
795 * setup, we can consider caching later.
798 * Datapath Node Identifier
800 * @return If the data at the supplied path exists, returns a list of all termination point
803 public List<OvsdbTerminationPointAugmentation> getPortsOnBridge(BigInteger dpnId) {
804 List<OvsdbTerminationPointAugmentation> ports = new ArrayList<>();
805 List<TerminationPoint> portList = interfaceMetaUtils.getTerminationPointsOnBridge(dpnId);
806 for (TerminationPoint ovsPort : portList) {
807 if (ovsPort.getAugmentation(OvsdbTerminationPointAugmentation.class) != null) {
808 ports.add(ovsPort.getAugmentation(OvsdbTerminationPointAugmentation.class));
811 LOG.debug("Found {} ports on bridge {}", ports.size(), dpnId);
816 * Get all termination points of type tunnel on a given DPN.
819 * Datapath Node Identifier
821 * @return If the data at the supplied path exists, returns a list of all termination point
822 * Augmentations of type tunnel
825 public List<OvsdbTerminationPointAugmentation> getTunnelPortsOnBridge(BigInteger dpnId) {
826 List<OvsdbTerminationPointAugmentation> tunnelPorts = new ArrayList<>();
827 List<TerminationPoint> portList = interfaceMetaUtils.getTerminationPointsOnBridge(dpnId);
828 for (TerminationPoint ovsPort : portList) {
829 OvsdbTerminationPointAugmentation portAug =
830 ovsPort.getAugmentation(OvsdbTerminationPointAugmentation.class);
831 if (portAug != null && SouthboundUtils.isInterfaceTypeTunnel(portAug.getInterfaceType())) {
832 tunnelPorts.add(portAug);
836 LOG.debug("Found {} tunnel ports on bridge {}", tunnelPorts.size(), dpnId);
841 * Get all termination points by type on a given DPN.
844 * Datapath Node Identifier
846 * @return If the data at the supplied path exists, returns a Map where key is interfaceType
847 * and value is list of termination points of given type
850 public Map<Class<? extends InterfaceTypeBase>, List<OvsdbTerminationPointAugmentation>>
851 getPortsOnBridgeByType(BigInteger dpnId) {
853 Map<Class<? extends InterfaceTypeBase>, List<OvsdbTerminationPointAugmentation>> portMap;
854 portMap = new ConcurrentHashMap<>();
855 List<TerminationPoint> ovsPorts = interfaceMetaUtils.getTerminationPointsOnBridge(dpnId);
856 if (ovsPorts != null) {
857 for (TerminationPoint ovsPort : ovsPorts) {
858 OvsdbTerminationPointAugmentation portAug =
859 ovsPort.getAugmentation(OvsdbTerminationPointAugmentation.class);
860 if (portAug != null && portAug.getInterfaceType() != null) {
861 portMap.computeIfAbsent(portAug.getInterfaceType(), k -> new ArrayList<>()).add(portAug);
869 public long getLogicalTunnelSelectGroupId(int lportTag) {
870 return IfmUtil.getLogicalTunnelSelectGroupId(lportTag);
874 public boolean isItmDirectTunnelsEnabled() {
875 return ifmConfig.isItmDirectTunnels();