2 * Copyright (c) 2016 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 org.opendaylight.controller.md.sal.binding.api.DataBroker;
12 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
13 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
14 import org.opendaylight.genius.interfacemanager.IfmUtil;
15 import org.opendaylight.genius.interfacemanager.commons.AlivenessMonitorUtils;
16 import org.opendaylight.genius.interfacemanager.commons.InterfaceManagerCommonUtils;
17 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.AlivenessMonitorService;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnel;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
27 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
31 import java.util.ArrayList;
32 import java.util.List;
34 public class OvsInterfaceStateUpdateHelper {
35 private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceStateUpdateHelper.class);
37 public static List<ListenableFuture<Void>> updateState(InstanceIdentifier<FlowCapableNodeConnector> key,
38 AlivenessMonitorService alivenessMonitorService,
39 DataBroker dataBroker, String interfaceName,
40 FlowCapableNodeConnector flowCapableNodeConnectorNew,
41 FlowCapableNodeConnector flowCapableNodeConnectorOld) {
42 LOG.debug("Update of Interface State for port: {}", interfaceName);
43 List<ListenableFuture<Void>> futures = new ArrayList<>();
44 WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
46 Interface.OperStatus operStatusNew = getOpState(flowCapableNodeConnectorNew);
47 MacAddress macAddressNew = flowCapableNodeConnectorNew.getHardwareAddress();
49 Interface.OperStatus operStatusOld = getOpState(flowCapableNodeConnectorOld);
50 MacAddress macAddressOld = flowCapableNodeConnectorOld.getHardwareAddress();
52 boolean opstateModified = false;
53 boolean hardwareAddressModified = false;
54 if (!operStatusNew.equals(operStatusOld)) {
55 opstateModified = true;
57 if (!macAddressNew.equals(macAddressOld)) {
58 hardwareAddressModified = true;
61 if (!opstateModified && !hardwareAddressModified) {
62 LOG.debug("If State entry for port: {} Not Modified.", interfaceName);
66 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface =
67 InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceName, dataBroker);
69 // For tunnels, derive the final opstate based on the bfd tunnel monitoring status
70 if(modifyTunnel(iface, opstateModified) && InterfaceManagerCommonUtils.checkIfBfdStateIsDown(iface.getName())){
71 operStatusNew = Interface.OperStatus.Down;
72 opstateModified = operStatusNew.equals(operStatusOld);
75 if (!opstateModified && !hardwareAddressModified) {
76 LOG.debug("If State entry for port: {} Not Modified.", interfaceName);
79 InterfaceBuilder ifaceBuilder = new InterfaceBuilder();
80 if (hardwareAddressModified) {
81 LOG.debug("Hw-Address Modified for Port: {}", interfaceName);
82 PhysAddress physAddress = new PhysAddress(macAddressNew.getValue());
83 ifaceBuilder.setPhysAddress(physAddress);
85 // modify the attributes in interface operational DS
86 handleInterfaceStateUpdates(iface, transaction, dataBroker,
87 ifaceBuilder, opstateModified, interfaceName, flowCapableNodeConnectorNew.getName(), operStatusNew);
89 // start/stop monitoring based on opState
90 if(modifyTunnel(iface, opstateModified)){
91 handleTunnelMonitoringUpdates(alivenessMonitorService, dataBroker, iface.getAugmentation(IfTunnel.class),
92 iface.getName(), operStatusNew);
95 futures.add(transaction.submit());
99 public static void updateInterfaceStateOnNodeRemove(String interfaceName, FlowCapableNodeConnector flowCapableNodeConnector,
100 DataBroker dataBroker, AlivenessMonitorService alivenessMonitorService,
101 WriteTransaction transaction){
102 LOG.debug("Updating interface oper-status to UNKNOWN for : {}", interfaceName);
104 InterfaceBuilder ifaceBuilder = new InterfaceBuilder();
105 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface =
106 InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceName, dataBroker);
107 handleInterfaceStateUpdates(iface,transaction, dataBroker,
108 ifaceBuilder, true, interfaceName, flowCapableNodeConnector.getName(),
109 Interface.OperStatus.Unknown);
110 if (InterfaceManagerCommonUtils.isTunnelInterface(iface)){
111 handleTunnelMonitoringUpdates(alivenessMonitorService, dataBroker, iface.getAugmentation(IfTunnel.class),
112 interfaceName, Interface.OperStatus.Unknown);
116 public static Interface.OperStatus getOpState(FlowCapableNodeConnector flowCapableNodeConnector){
117 Interface.OperStatus operStatus =
118 (flowCapableNodeConnector.getState().isLive() &&
119 !flowCapableNodeConnector.getConfiguration().isPORTDOWN())
120 ? Interface.OperStatus.Up: Interface.OperStatus.Down;
124 public static void handleInterfaceStateUpdates(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface,
125 WriteTransaction transaction, DataBroker dataBroker, 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 lower-layer-interfaces
128 // which have no corresponding config entries
129 if(iface == null && !interfaceName.equals(portName)) {
132 LOG.debug("updating interface state entry for {}", interfaceName);
133 InstanceIdentifier<Interface> ifStateId = IfmUtil.buildStateInterfaceId(interfaceName);
134 ifaceBuilder.setKey(new InterfaceKey(interfaceName));
135 if (modifyOpState(iface, opStateModified)) {
136 LOG.debug("updating interface oper status as {} for {}", opState.name(), interfaceName);
137 ifaceBuilder.setOperStatus(opState);
139 transaction.merge(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build(), false);
142 public static void handleTunnelMonitoringUpdates(AlivenessMonitorService alivenessMonitorService, DataBroker dataBroker,
143 IfTunnel ifTunnel, String interfaceName,
144 Interface.OperStatus operStatus){
146 LOG.debug("handling tunnel monitoring updates for {} due to opstate modification", interfaceName);
147 if (operStatus == Interface.OperStatus.Down || operStatus == Interface.OperStatus.Unknown)
148 AlivenessMonitorUtils.stopLLDPMonitoring(alivenessMonitorService, dataBroker, ifTunnel, interfaceName);
150 AlivenessMonitorUtils.startLLDPMonitoring(alivenessMonitorService, dataBroker, ifTunnel, interfaceName);
153 public static boolean modifyOpState(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface,
154 boolean opStateModified){
155 return (opStateModified && (iface == null || iface != null && iface.isEnabled()));
158 public static boolean modifyTunnel(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface,
159 boolean opStateModified){
160 return modifyOpState(iface, opStateModified) && iface != null && iface.getAugmentation(IfTunnel.class) != null;