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