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.ArrayList;
12 import java.util.List;
13 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
14 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
15 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
16 import org.opendaylight.genius.interfacemanager.IfmUtil;
17 import org.opendaylight.genius.interfacemanager.commons.AlivenessMonitorUtils;
18 import org.opendaylight.genius.interfacemanager.commons.InterfaceManagerCommonUtils;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.AlivenessMonitorService;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnel;
27 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
31 public class OvsInterfaceStateUpdateHelper {
32 private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceStateUpdateHelper.class);
34 public static List<ListenableFuture<Void>> updateState(InstanceIdentifier<FlowCapableNodeConnector> key,
35 AlivenessMonitorService alivenessMonitorService, DataBroker dataBroker, String interfaceName,
36 FlowCapableNodeConnector flowCapableNodeConnectorNew,
37 FlowCapableNodeConnector flowCapableNodeConnectorOld) {
38 LOG.debug("Update of Interface State for port: {}", interfaceName);
39 List<ListenableFuture<Void>> futures = new ArrayList<>();
41 Interface.OperStatus operStatusNew = getOpState(flowCapableNodeConnectorNew);
42 MacAddress macAddressNew = flowCapableNodeConnectorNew.getHardwareAddress();
44 Interface.OperStatus operStatusOld = getOpState(flowCapableNodeConnectorOld);
45 MacAddress macAddressOld = flowCapableNodeConnectorOld.getHardwareAddress();
47 boolean opstateModified = false;
48 boolean hardwareAddressModified = false;
49 if (!operStatusNew.equals(operStatusOld)) {
50 opstateModified = true;
52 if (!macAddressNew.equals(macAddressOld)) {
53 hardwareAddressModified = true;
56 if (!opstateModified && !hardwareAddressModified) {
57 LOG.debug("If State entry for port: {} Not Modified.", interfaceName);
61 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
62 .interfaces.rev140508.interfaces.Interface iface = InterfaceManagerCommonUtils
63 .getInterfaceFromConfigDS(interfaceName, dataBroker);
65 // For monitoring enabled tunnels, skip opstate update
66 if (isTunnelInterface(iface) && !modifyTunnelOpState(iface, opstateModified)) {
67 LOG.debug("skip interface-state updation for monitoring enabled tunnel interface {}", interfaceName);
68 opstateModified = false;
71 if (!opstateModified && !hardwareAddressModified) {
72 LOG.debug("If State entry for port: {} Not Modified.", interfaceName);
75 InterfaceBuilder ifaceBuilder = new InterfaceBuilder();
76 if (hardwareAddressModified) {
77 LOG.debug("Hw-Address Modified for Port: {}", interfaceName);
78 PhysAddress physAddress = new PhysAddress(macAddressNew.getValue());
79 ifaceBuilder.setPhysAddress(physAddress);
81 // modify the attributes in interface operational DS
82 WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
83 handleInterfaceStateUpdates(iface, transaction, dataBroker, ifaceBuilder, opstateModified, interfaceName,
84 flowCapableNodeConnectorNew.getName(), operStatusNew);
86 // start/stop monitoring based on opState
87 if (isTunnelInterface(iface) && opstateModified) {
88 handleTunnelMonitoringUpdates(alivenessMonitorService, dataBroker, iface.getAugmentation(IfTunnel.class),
89 iface.getName(), operStatusNew);
92 futures.add(transaction.submit());
96 public static void updateInterfaceStateOnNodeRemove(String interfaceName,
97 FlowCapableNodeConnector flowCapableNodeConnector, DataBroker dataBroker,
98 AlivenessMonitorService alivenessMonitorService, WriteTransaction transaction) {
99 LOG.debug("Updating interface oper-status to UNKNOWN for : {}", interfaceName);
101 InterfaceBuilder ifaceBuilder = new InterfaceBuilder();
102 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
103 .ietf.interfaces.rev140508.interfaces.Interface iface = InterfaceManagerCommonUtils
104 .getInterfaceFromConfigDS(interfaceName, dataBroker);
105 handleInterfaceStateUpdates(iface, transaction, dataBroker, ifaceBuilder, true, interfaceName,
106 flowCapableNodeConnector.getName(), Interface.OperStatus.Unknown);
107 if (InterfaceManagerCommonUtils.isTunnelInterface(iface)) {
108 handleTunnelMonitoringUpdates(alivenessMonitorService, dataBroker, iface.getAugmentation(IfTunnel.class),
109 interfaceName, Interface.OperStatus.Unknown);
113 public static Interface.OperStatus getOpState(FlowCapableNodeConnector flowCapableNodeConnector) {
114 Interface.OperStatus operStatus = flowCapableNodeConnector.getState().isLive()
115 && !flowCapableNodeConnector.getConfiguration().isPORTDOWN() ? Interface.OperStatus.Up
116 : Interface.OperStatus.Down;
120 public static void handleInterfaceStateUpdates(
121 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
122 .ietf.interfaces.rev140508.interfaces.Interface iface,
123 WriteTransaction transaction, DataBroker dataBroker, InterfaceBuilder ifaceBuilder, boolean opStateModified,
124 String interfaceName, String portName, Interface.OperStatus opState) {
125 // if interface config DS is null, do the update only for the
126 // lower-layer-interfaces
127 // which have no corresponding config entries
128 if (iface == null && !interfaceName.equals(portName)) {
131 LOG.debug("updating interface state entry for {}", interfaceName);
132 InstanceIdentifier<Interface> ifStateId = IfmUtil.buildStateInterfaceId(interfaceName);
133 ifaceBuilder.setKey(new InterfaceKey(interfaceName));
134 if (modifyOpState(iface, opStateModified)) {
135 LOG.debug("updating interface oper status as {} for {}", opState.name(), interfaceName);
136 ifaceBuilder.setOperStatus(opState);
138 transaction.merge(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build(), false);
141 public static void handleTunnelMonitoringUpdates(AlivenessMonitorService alivenessMonitorService,
142 DataBroker dataBroker, IfTunnel ifTunnel, String interfaceName, Interface.OperStatus operStatus) {
143 LOG.debug("handling tunnel monitoring updates for {} due to opstate modification", interfaceName);
144 if (operStatus == Interface.OperStatus.Down || operStatus == Interface.OperStatus.Unknown) {
145 AlivenessMonitorUtils.stopLLDPMonitoring(alivenessMonitorService, dataBroker, ifTunnel, interfaceName);
147 AlivenessMonitorUtils.startLLDPMonitoring(alivenessMonitorService, dataBroker, ifTunnel, interfaceName);
151 public static boolean modifyOpState(
152 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
153 .interfaces.rev140508.interfaces.Interface iface,
154 boolean opStateModified) {
155 return opStateModified && (iface == null || iface != null && iface.isEnabled());
158 public static boolean isTunnelInterface(
159 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
160 .ietf.interfaces.rev140508.interfaces.Interface iface) {
161 return iface != null && iface.getAugmentation(IfTunnel.class) != null;
164 public static boolean modifyTunnelOpState(
165 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
166 .ietf.interfaces.rev140508.interfaces.Interface iface,
167 boolean opStateModified) {
168 if (!iface.getAugmentation(IfTunnel.class).isMonitorEnabled()) {
169 return modifyOpState(iface, opStateModified);