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 com.google.common.util.concurrent.ListenableFuture;
11 import java.util.Collections;
12 import java.util.List;
13 import javax.inject.Inject;
14 import javax.inject.Singleton;
15 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
16 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
17 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
18 import org.opendaylight.genius.interfacemanager.IfmUtil;
19 import org.opendaylight.genius.interfacemanager.commons.AlivenessMonitorUtils;
20 import org.opendaylight.genius.interfacemanager.commons.InterfaceManagerCommonUtils;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnel;
28 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
33 public class OvsInterfaceStateUpdateHelper {
34 private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceStateUpdateHelper.class);
36 private final DataBroker dataBroker;
37 private final InterfaceManagerCommonUtils interfaceManagerCommonUtils;
38 private final AlivenessMonitorUtils alivenessMonitorUtils;
41 public OvsInterfaceStateUpdateHelper(DataBroker dataBroker, AlivenessMonitorUtils alivenessMonitorUtils,
42 InterfaceManagerCommonUtils interfaceManagerCommonUtils) {
43 this.dataBroker = dataBroker;
44 this.interfaceManagerCommonUtils = interfaceManagerCommonUtils;
45 this.alivenessMonitorUtils = alivenessMonitorUtils;
48 public List<ListenableFuture<Void>> updateState(String interfaceName,
49 FlowCapableNodeConnector flowCapableNodeConnectorNew,
50 FlowCapableNodeConnector flowCapableNodeConnectorOld) {
51 LOG.debug("Updating interface state information for interface: {}", interfaceName);
53 Interface.OperStatus operStatusNew = InterfaceManagerCommonUtils.getOpState(flowCapableNodeConnectorNew);
54 MacAddress macAddressNew = flowCapableNodeConnectorNew.getHardwareAddress();
56 Interface.OperStatus operStatusOld = InterfaceManagerCommonUtils.getOpState(flowCapableNodeConnectorOld);
57 MacAddress macAddressOld = flowCapableNodeConnectorOld.getHardwareAddress();
59 boolean opstateModified = false;
60 boolean hardwareAddressModified = false;
61 if (!operStatusNew.equals(operStatusOld)) {
62 opstateModified = true;
64 if (!macAddressNew.equals(macAddressOld)) {
65 hardwareAddressModified = true;
68 if (!opstateModified && !hardwareAddressModified) {
69 LOG.debug("If State entry for port: {} Not Modified.", interfaceName);
70 return Collections.emptyList();
73 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
74 .interfaces.rev140508.interfaces.Interface iface = interfaceManagerCommonUtils
75 .getInterfaceFromConfigDS(interfaceName);
77 // For monitoring enabled tunnels, skip opstate update
78 if (isTunnelInterface(iface) && !modifyTunnelOpState(iface, opstateModified)) {
79 LOG.debug("skip interface-state updation for monitoring enabled tunnel interface {}", interfaceName);
80 opstateModified = false;
83 if (!opstateModified && !hardwareAddressModified) {
84 LOG.debug("If State entry for port: {} Not Modified.", interfaceName);
85 return Collections.emptyList();
87 InterfaceBuilder ifaceBuilder = new InterfaceBuilder();
88 if (hardwareAddressModified) {
89 LOG.debug("Hw-Address Modified for Port: {}", interfaceName);
90 PhysAddress physAddress = new PhysAddress(macAddressNew.getValue());
91 ifaceBuilder.setPhysAddress(physAddress);
93 // modify the attributes in interface operational DS
94 WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
95 handleInterfaceStateUpdates(iface, transaction, ifaceBuilder, opstateModified, interfaceName,
96 flowCapableNodeConnectorNew.getName(), operStatusNew);
98 // start/stop monitoring based on opState
99 if (isTunnelInterface(iface) && opstateModified) {
100 handleTunnelMonitoringUpdates(iface.getAugmentation(IfTunnel.class), iface.getName(), operStatusNew);
103 return Collections.singletonList(transaction.submit());
106 public void updateInterfaceStateOnNodeRemove(String interfaceName,
107 FlowCapableNodeConnector flowCapableNodeConnector, WriteTransaction transaction) {
108 LOG.debug("Updating interface oper-status to UNKNOWN for : {}", interfaceName);
110 InterfaceBuilder ifaceBuilder = new InterfaceBuilder();
111 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
112 .ietf.interfaces.rev140508.interfaces.Interface iface = interfaceManagerCommonUtils
113 .getInterfaceFromConfigDS(interfaceName);
114 handleInterfaceStateUpdates(iface, transaction, ifaceBuilder, true, interfaceName,
115 flowCapableNodeConnector.getName(), Interface.OperStatus.Unknown);
116 if (InterfaceManagerCommonUtils.isTunnelInterface(iface)) {
117 handleTunnelMonitoringUpdates(iface.getAugmentation(IfTunnel.class), interfaceName,
118 Interface.OperStatus.Unknown);
122 public static void handleInterfaceStateUpdates(
123 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
124 .ietf.interfaces.rev140508.interfaces.Interface iface,
125 WriteTransaction transaction, InterfaceBuilder ifaceBuilder, boolean opStateModified,
126 String interfaceName, String portName, Interface.OperStatus opState) {
127 // if interface config DS is null, do the update only for the
128 // lower-layer-interfaces
129 // which have no corresponding config entries
130 if (iface == null && !interfaceName.equals(portName)) {
133 LOG.debug("updating interface state entry for {}", interfaceName);
134 InstanceIdentifier<Interface> ifStateId = IfmUtil.buildStateInterfaceId(interfaceName);
135 ifaceBuilder.setKey(new InterfaceKey(interfaceName));
136 if (modifyOpState(iface, opStateModified)) {
137 LOG.debug("updating interface oper status as {} for {}", opState.name(), interfaceName);
138 ifaceBuilder.setOperStatus(opState);
140 transaction.merge(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build(), false);
143 public void handleTunnelMonitoringUpdates(IfTunnel ifTunnel,
144 String interfaceName, Interface.OperStatus operStatus) {
145 LOG.debug("handling tunnel monitoring updates for {} due to opstate modification", interfaceName);
146 if (operStatus == Interface.OperStatus.Down || operStatus == Interface.OperStatus.Unknown) {
147 alivenessMonitorUtils.stopLLDPMonitoring(ifTunnel, interfaceName);
149 alivenessMonitorUtils.startLLDPMonitoring(ifTunnel, interfaceName);
153 public static boolean modifyOpState(
154 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
155 .interfaces.rev140508.interfaces.Interface iface,
156 boolean opStateModified) {
157 return opStateModified && (iface == null || iface != null && iface.isEnabled());
160 public static boolean isTunnelInterface(
161 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
162 .ietf.interfaces.rev140508.interfaces.Interface iface) {
163 return iface != null && iface.getAugmentation(IfTunnel.class) != null;
166 public static boolean modifyTunnelOpState(
167 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
168 .ietf.interfaces.rev140508.interfaces.Interface iface,
169 boolean opStateModified) {
170 if (!iface.getAugmentation(IfTunnel.class).isMonitorEnabled()) {
171 return modifyOpState(iface, opStateModified);