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.renderer.ovs.statehelpers;
10 import static org.opendaylight.genius.infra.Datastore.OPERATIONAL;
12 import com.google.common.util.concurrent.ListenableFuture;
13 import java.util.Collections;
14 import java.util.List;
15 import java.util.Objects;
16 import javax.inject.Inject;
17 import javax.inject.Singleton;
19 import org.apache.aries.blueprint.annotation.service.Reference;
20 import org.opendaylight.genius.infra.Datastore.Operational;
21 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
22 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
23 import org.opendaylight.genius.infra.TypedWriteTransaction;
24 import org.opendaylight.genius.interfacemanager.IfmUtil;
25 import org.opendaylight.genius.interfacemanager.commons.AlivenessMonitorUtils;
26 import org.opendaylight.genius.interfacemanager.commons.InterfaceManagerCommonUtils;
27 import org.opendaylight.mdsal.binding.api.DataBroker;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnel;
35 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
40 public class OvsInterfaceStateUpdateHelper {
41 private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceStateUpdateHelper.class);
43 private final ManagedNewTransactionRunner txRunner;
44 private final InterfaceManagerCommonUtils interfaceManagerCommonUtils;
45 private final AlivenessMonitorUtils alivenessMonitorUtils;
48 public OvsInterfaceStateUpdateHelper(@Reference DataBroker dataBroker,
49 AlivenessMonitorUtils alivenessMonitorUtils,
50 InterfaceManagerCommonUtils interfaceManagerCommonUtils) {
51 this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
52 this.interfaceManagerCommonUtils = interfaceManagerCommonUtils;
53 this.alivenessMonitorUtils = alivenessMonitorUtils;
56 public List<ListenableFuture<Void>> updateState(String interfaceName,
57 FlowCapableNodeConnector flowCapableNodeConnectorNew,
58 FlowCapableNodeConnector flowCapableNodeConnectorOld) {
59 LOG.debug("Updating interface state information for interface: {}", interfaceName);
61 Interface.OperStatus operStatusNew = InterfaceManagerCommonUtils.getOpState(flowCapableNodeConnectorNew);
62 MacAddress macAddressNew = flowCapableNodeConnectorNew.getHardwareAddress();
64 Interface.OperStatus operStatusOld = InterfaceManagerCommonUtils.getOpState(flowCapableNodeConnectorOld);
65 MacAddress macAddressOld = flowCapableNodeConnectorOld.getHardwareAddress();
67 boolean opstateModified = !operStatusNew.equals(operStatusOld);
68 boolean hardwareAddressModified = !Objects.equals(macAddressNew, macAddressOld);
70 if (!opstateModified && !hardwareAddressModified) {
71 LOG.debug("If State entry for port: {} Not Modified.", interfaceName);
72 return Collections.emptyList();
75 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
76 .interfaces.rev140508.interfaces.Interface iface = interfaceManagerCommonUtils
77 .getInterfaceFromConfigDS(interfaceName);
79 // For monitoring enabled tunnels, skip opstate update
80 if (isTunnelInterface(iface) && !modifyTunnelOpState(iface, opstateModified)) {
81 LOG.debug("skip interface-state updation for monitoring enabled tunnel interface {}", interfaceName);
82 opstateModified = false;
85 if (!opstateModified && !hardwareAddressModified) {
86 LOG.debug("If State entry for port: {} Not Modified.", interfaceName);
87 return Collections.emptyList();
89 InterfaceBuilder ifaceBuilder = new InterfaceBuilder();
90 if (hardwareAddressModified) {
91 LOG.debug("Hw-Address Modified for Port: {}", interfaceName);
92 PhysAddress physAddress = new PhysAddress(macAddressNew.getValue());
93 ifaceBuilder.setPhysAddress(physAddress);
96 if (opstateModified) {
97 return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL, tx -> {
98 // modify the attributes in interface operational DS
99 handleInterfaceStateUpdates(iface, tx, ifaceBuilder, true, interfaceName,
100 flowCapableNodeConnectorNew.getName(), operStatusNew);
102 // start/stop monitoring based on opState
103 if (isTunnelInterface(iface)) {
104 handleTunnelMonitoringUpdates(iface.augmentation(IfTunnel.class), iface.getName(),
109 return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL, tx -> {
110 // modify the attributes in interface operational DS
111 handleInterfaceStateUpdates(iface, tx, ifaceBuilder, false, interfaceName,
112 flowCapableNodeConnectorNew.getName(), operStatusNew);
117 public void updateInterfaceStateOnNodeRemove(String interfaceName,
118 FlowCapableNodeConnector flowCapableNodeConnector, TypedWriteTransaction<Operational> tx) {
119 LOG.debug("Updating interface oper-status to UNKNOWN for : {}", interfaceName);
121 InterfaceBuilder ifaceBuilder = new InterfaceBuilder();
122 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
123 .ietf.interfaces.rev140508.interfaces.Interface iface = interfaceManagerCommonUtils
124 .getInterfaceFromConfigDS(interfaceName);
125 handleInterfaceStateUpdates(iface, tx, ifaceBuilder, true, interfaceName,
126 flowCapableNodeConnector.getName(), Interface.OperStatus.Unknown);
127 if (InterfaceManagerCommonUtils.isTunnelInterface(iface)) {
128 handleTunnelMonitoringUpdates(iface.augmentation(IfTunnel.class), interfaceName,
129 Interface.OperStatus.Unknown);
133 private void handleInterfaceStateUpdates(
134 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
135 .ietf.interfaces.rev140508.interfaces.Interface iface,
136 TypedWriteTransaction<Operational> tx, InterfaceBuilder ifaceBuilder, boolean opStateModified,
137 String interfaceName, String portName, Interface.OperStatus opState) {
138 // if interface config DS is null, do the update only for the
139 // lower-layer-interfaces
140 // which have no corresponding config entries
141 if (iface == null && !interfaceName.equals(portName)) {
145 final Interface interfaceState = interfaceManagerCommonUtils.getInterfaceStateFromOperDS(interfaceName);
146 if (interfaceState == null || (interfaceState.getOperStatus() == opState)) {
147 LOG.warn("Ignoring: updating interface state for interface {}",
152 LOG.debug("updating interface state entry for {}", interfaceName);
153 InstanceIdentifier<Interface> ifStateId = IfmUtil.buildStateInterfaceId(interfaceName);
154 ifaceBuilder.withKey(new InterfaceKey(interfaceName));
155 if (modifyOpState(iface, opStateModified)) {
156 LOG.debug("updating interface oper status as {} for {}", opState.name(), interfaceName);
157 ifaceBuilder.setOperStatus(opState);
159 tx.merge(ifStateId, ifaceBuilder.build());
162 public void handleTunnelMonitoringUpdates(IfTunnel ifTunnel,
163 String interfaceName, Interface.OperStatus operStatus) {
164 LOG.debug("handling tunnel monitoring updates for {} due to opstate modification", interfaceName);
165 if (operStatus == Interface.OperStatus.Down || operStatus == Interface.OperStatus.Unknown) {
166 alivenessMonitorUtils.stopLLDPMonitoring(ifTunnel, interfaceName);
168 alivenessMonitorUtils.startLLDPMonitoring(ifTunnel, interfaceName);
172 public static boolean modifyOpState(
173 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
174 .interfaces.rev140508.interfaces.Interface iface,
175 boolean opStateModified) {
176 return opStateModified && (iface == null || iface.isEnabled());
179 public static boolean isTunnelInterface(
180 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
181 .ietf.interfaces.rev140508.interfaces.Interface iface) {
182 return iface != null && iface.augmentation(IfTunnel.class) != null;
185 public static boolean modifyTunnelOpState(
186 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
187 .ietf.interfaces.rev140508.interfaces.Interface iface,
188 boolean opStateModified) {
189 if (!iface.augmentation(IfTunnel.class).isMonitorEnabled()) {
190 return modifyOpState(iface, opStateModified);