genius/interfacemanager annotation based bp
[genius.git] / interfacemanager / interfacemanager-impl / src / main / java / org / opendaylight / genius / interfacemanager / renderer / ovs / utilities / SouthboundUtils.java
1 /*
2  * Copyright (c) 2016, 2017 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.genius.interfacemanager.renderer.ovs.utilities;
9
10 import static org.opendaylight.controller.md.sal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
11
12 import com.google.common.collect.Maps;
13 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
14 import java.math.BigInteger;
15 import java.util.ArrayList;
16 import java.util.HashMap;
17 import java.util.List;
18 import java.util.Locale;
19 import java.util.Map;
20 import java.util.UUID;
21 import javax.inject.Inject;
22 import javax.inject.Singleton;
23
24 import org.apache.aries.blueprint.annotation.service.Reference;
25 import org.apache.commons.lang3.BooleanUtils;
26 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
27 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
28 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
29 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
30 import org.opendaylight.genius.infra.Datastore.Configuration;
31 import org.opendaylight.genius.infra.TypedWriteTransaction;
32 import org.opendaylight.genius.interfacemanager.InterfacemgrProvider;
33 import org.opendaylight.genius.interfacemanager.commons.InterfaceManagerCommonUtils;
34 import org.opendaylight.genius.interfacemanager.globals.IfmConstants;
35 import org.opendaylight.infrautils.caches.Cache;
36 import org.opendaylight.infrautils.caches.CacheConfigBuilder;
37 import org.opendaylight.infrautils.caches.CachePolicyBuilder;
38 import org.opendaylight.infrautils.caches.CacheProvider;
39 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
40 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge._interface.info.BridgeEntry;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge._interface.info.bridge.entry.BridgeInterfaceEntry;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnel;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelMonitoringTypeBfd;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeGre;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeMplsOverGre;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlanGpe;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.tunnel.optional.params.TunnelOptions;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeBase;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeGre;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeVxlan;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbPortInterfaceAttributes;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentationBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceBfd;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceBfdBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceBfdKey;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Options;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsKey;
68 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
69 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
70 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
71 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
72 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
73 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
74 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
75 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
76 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
77 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
78 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
79 import org.slf4j.Logger;
80 import org.slf4j.LoggerFactory;
81
82 @Singleton
83 public class SouthboundUtils {
84     private static final Logger LOG = LoggerFactory.getLogger(SouthboundUtils.class);
85
86     private static final String BFD_PARAM_ENABLE = "enable";
87     private static final String BFD_PARAM_MIN_TX = "min_tx";
88     private static final String BFD_PARAM_FORWARDING_IF_RX = "forwarding_if_rx";
89
90     // BFD parameters
91     public static final String BFD_ENABLE_KEY = "enable";
92     public static final String BFD_ENABLE_VALUE = "true";
93     public static final String BFD_OP_STATE = "state";
94     public static final String BFD_STATE_UP = "up";
95     private static final String BFD_MIN_TX_VAL = "100";
96     private static final String BFD_FORWARDING_IF_RX_VAL = "true";
97
98     // Tunnel options
99     private static final String TUNNEL_OPTIONS_KEY = "key";
100     private static final String TUNNEL_OPTIONS_LOCAL_IP = "local_ip";
101     private static final String TUNNEL_OPTIONS_REMOTE_IP = "remote_ip";
102     private static final String TUNNEL_OPTIONS_DESTINATION_PORT = "dst_port";
103
104     // Option values for VxLAN-GPE + NSH tunnels
105     private static final String TUNNEL_OPTIONS_EXTS = "exts";
106     private static final String TUNNEL_OPTIONS_NSI = "nsi";
107     private static final String TUNNEL_OPTIONS_NSP = "nsp";
108     private static final String TUNNEL_OPTIONS_NSHC1 = "nshc1";
109     private static final String TUNNEL_OPTIONS_NSHC2 = "nshc2";
110     private static final String TUNNEL_OPTIONS_NSHC3 = "nshc3";
111     private static final String TUNNEL_OPTIONS_NSHC4 = "nshc4";
112
113     // Tunnel options for MPLS-GRE tunnels [requires OVS 2.8+)
114     private static final String TUNNEL_OPTIONS_PKT_TYPE = "packet_type";
115
116     // Option values for VxLAN-GPE + NSH tunnels
117     private static final String TUNNEL_OPTIONS_VALUE_FLOW = "flow";
118     private static final String TUNNEL_OPTIONS_VALUE_GPE = "gpe";
119     // UDP port for VxLAN-GPE Tunnels
120     private static final String TUNNEL_OPTIONS_VALUE_GPE_DESTINATION_PORT = "4880";
121
122     // Tunnel option values for MPLS-GRE tunnels [requires OVS 2.8+)
123     private static final String TUNNEL_OPTIONS_VALUE_LEGACY_L3 = "legacy_l3";
124
125     // To keep the mapping between Tunnel Types and Tunnel Interfaces
126     private static final Map<Class<? extends TunnelTypeBase>, Class<? extends InterfaceTypeBase>>
127         TUNNEL_TYPE_MAP = new HashMap<Class<? extends TunnelTypeBase>, Class<? extends InterfaceTypeBase>>() {
128             {
129                 put(TunnelTypeGre.class, InterfaceTypeGre.class);
130                 put(TunnelTypeMplsOverGre.class, InterfaceTypeGre.class);
131                 put(TunnelTypeVxlan.class, InterfaceTypeVxlan.class);
132                 put(TunnelTypeVxlanGpe.class, InterfaceTypeVxlan.class);
133             }
134         };
135
136     // OVS Detection statics
137     private static final String DEFAULT_OVS_VERSION = "2.8.0";
138     private static final String MIN_GRE_VERSION = "2.8.0";
139     private static final long MAX_CACHE_SIZE = 1024;
140
141     private final SingleTransactionDataBroker singleTxDB;
142
143     private final BatchingUtils batchingUtils;
144     private final InterfacemgrProvider interfacemgrProvider;
145     private final Cache<String, String> ovsVersionCache;
146
147     @Inject
148     public SouthboundUtils(@Reference final DataBroker dataBroker,
149                            final BatchingUtils batchingUtils, InterfacemgrProvider interfacemgrProvider,
150                            @Reference final CacheProvider cacheProvider) {
151         this.batchingUtils = batchingUtils;
152         this.interfacemgrProvider = interfacemgrProvider;
153         this.singleTxDB = new SingleTransactionDataBroker(dataBroker);
154         ovsVersionCache = cacheProvider.newCache(
155                 new CacheConfigBuilder<String, String>()
156                         .anchor(this)
157                         .id("ovsVersionCache")
158                         .cacheFunction(key -> getVersionForBridgeNodeId(key))
159                         .description("BridgeNodeId to OVS Version cache")
160                         .build(),
161                 new CachePolicyBuilder().maxEntries(MAX_CACHE_SIZE).build());
162     }
163
164     public void addPortToBridge(InstanceIdentifier<?> bridgeIid, Interface iface, String portName) {
165         IfTunnel ifTunnel = iface.augmentation(IfTunnel.class);
166         if (ifTunnel != null) {
167             addTunnelPortToBridge(ifTunnel, bridgeIid, iface, portName);
168         }
169     }
170
171     /*
172      * Add all tunnels ports corresponding to the bridge to the topology config DS.
173      */
174     public void addAllPortsToBridge(BridgeEntry bridgeEntry, InterfaceManagerCommonUtils interfaceManagerCommonUtils,
175                                     InstanceIdentifier<OvsdbBridgeAugmentation> bridgeIid,
176                                     OvsdbBridgeAugmentation bridgeNew) {
177         String bridgeName = bridgeNew.getBridgeName().getValue();
178         LOG.debug("adding all ports to bridge: {}", bridgeName);
179         List<BridgeInterfaceEntry> bridgeInterfaceEntries = bridgeEntry.getBridgeInterfaceEntry();
180         if (bridgeInterfaceEntries != null) {
181             for (BridgeInterfaceEntry bridgeInterfaceEntry : bridgeInterfaceEntries) {
182                 String portName = bridgeInterfaceEntry.getInterfaceName();
183                 InterfaceKey interfaceKey = new InterfaceKey(portName);
184                 Interface iface = interfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey);
185                 if (iface != null) {
186                     IfTunnel ifTunnel = iface.augmentation(IfTunnel.class);
187                     if (ifTunnel != null) {
188                         if (!(interfacemgrProvider.isItmDirectTunnelsEnabled() && ifTunnel.isInternal())) {
189                             addTunnelPortToBridge(ifTunnel, bridgeIid, iface, portName);
190                         }
191                         if (isOfTunnel(ifTunnel)) {
192                             LOG.debug("Using OFTunnel. Only one tunnel port will be added");
193                             return;
194                         }
195                     }
196                 } else {
197                     LOG.debug("Interface {} not found in config DS", portName);
198                 }
199             }
200         }
201     }
202
203     private void addTunnelPortToBridge(IfTunnel ifTunnel, InstanceIdentifier<?> bridgeIid, Interface iface,
204             String portName) {
205         LOG.debug("adding tunnel port {} to bridge {}", portName, bridgeIid);
206
207         Class<? extends InterfaceTypeBase> type = TUNNEL_TYPE_MAP.get(ifTunnel.getTunnelInterfaceType());
208
209         if (type == null) {
210             LOG.warn("Unknown Tunnel Type obtained while creating interface: {}", iface);
211             return;
212         }
213
214         int vlanId = 0;
215         IfL2vlan ifL2vlan = iface.augmentation(IfL2vlan.class);
216         if (ifL2vlan != null && ifL2vlan.getVlanId() != null) {
217             vlanId = ifL2vlan.getVlanId().getValue();
218         }
219
220         Map<String, String> options = Maps.newHashMap();
221
222         // Options common to any kind of tunnel
223         if (BooleanUtils.isTrue(ifTunnel.isTunnelSourceIpFlow())) {
224             options.put(TUNNEL_OPTIONS_LOCAL_IP, TUNNEL_OPTIONS_VALUE_FLOW);
225         } else {
226             IpAddress localIp = ifTunnel.getTunnelSource();
227             options.put(TUNNEL_OPTIONS_LOCAL_IP, localIp.stringValue());
228         }
229         if (BooleanUtils.isTrue(ifTunnel.isTunnelRemoteIpFlow())) {
230             options.put(TUNNEL_OPTIONS_REMOTE_IP, TUNNEL_OPTIONS_VALUE_FLOW);
231         } else {
232             IpAddress remoteIp = ifTunnel.getTunnelDestination();
233             options.put(TUNNEL_OPTIONS_REMOTE_IP, remoteIp.stringValue());
234         }
235         // Specific options for each type of tunnel
236         if (TunnelTypeMplsOverGre.class.equals(ifTunnel.getTunnelInterfaceType())) {
237             String switchVersion = getSwitchVersion((InstanceIdentifier<Node>) bridgeIid);
238             LOG.debug("Switch OVS Version: {}", switchVersion);
239             if (org.opendaylight.ovsdb.utils.southbound.utils.SouthboundUtils.compareDbVersionToMinVersion(
240                     switchVersion, MIN_GRE_VERSION)) {
241                 options.put(TUNNEL_OPTIONS_PKT_TYPE, TUNNEL_OPTIONS_VALUE_LEGACY_L3);
242             } else {
243                 LOG.warn("{} OVS version {} less than {} required for MplsOverGre",
244                         bridgeIid.firstKeyOf(Node.class).getNodeId().getValue(),
245                         switchVersion, MIN_GRE_VERSION);
246                 return;
247             }
248         } else {
249             options.put(TUNNEL_OPTIONS_KEY, TUNNEL_OPTIONS_VALUE_FLOW);
250         }
251         if (ifTunnel.getTunnelInterfaceType().equals(TunnelTypeVxlanGpe.class)) {
252             options.put(TUNNEL_OPTIONS_EXTS, TUNNEL_OPTIONS_VALUE_GPE);
253             options.put(TUNNEL_OPTIONS_NSI, TUNNEL_OPTIONS_VALUE_FLOW);
254             options.put(TUNNEL_OPTIONS_NSP, TUNNEL_OPTIONS_VALUE_FLOW);
255             options.put(TUNNEL_OPTIONS_NSHC1, TUNNEL_OPTIONS_VALUE_FLOW);
256             options.put(TUNNEL_OPTIONS_NSHC2, TUNNEL_OPTIONS_VALUE_FLOW);
257             options.put(TUNNEL_OPTIONS_NSHC3, TUNNEL_OPTIONS_VALUE_FLOW);
258             options.put(TUNNEL_OPTIONS_NSHC4, TUNNEL_OPTIONS_VALUE_FLOW);
259             // VxLAN-GPE interfaces will not use the default UDP port to avoid
260             // problems with other meshes
261             options.put(TUNNEL_OPTIONS_DESTINATION_PORT, TUNNEL_OPTIONS_VALUE_GPE_DESTINATION_PORT);
262         }
263
264         if (ifTunnel.getTunnelOptions() != null) {
265             for (TunnelOptions tunOpt : ifTunnel.getTunnelOptions()) {
266                 options.putIfAbsent(tunOpt.getTunnelOption(), tunOpt.getValue());
267             }
268         }
269
270         addTerminationPoint(bridgeIid, portName, vlanId, type, options, ifTunnel);
271     }
272
273     // Update is allowed only for tunnel monitoring attributes
274     public static void updateBfdParamtersForTerminationPoint(InstanceIdentifier<?> bridgeIid, IfTunnel ifTunnel,
275             String portName, TypedWriteTransaction<Configuration> transaction) {
276         InstanceIdentifier<TerminationPoint> tpIid = createTerminationPointInstanceIdentifier(
277                 InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(Node.class)), portName);
278         if (isOfTunnel(ifTunnel)) {
279             LOG.warn("BFD monitoring not supported for OFTunnels. Skipping BFD parameters for {}", portName);
280             return;
281         }
282         LOG.debug("update bfd parameters for interface {}", tpIid);
283         OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder();
284         List<InterfaceBfd> bfdParams = getBfdParams(ifTunnel);
285         tpAugmentationBuilder.setInterfaceBfd(bfdParams);
286
287         TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
288         tpBuilder.withKey(InstanceIdentifier.keyOf(tpIid));
289         tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
290
291         transaction.merge(tpIid, tpBuilder.build(), CREATE_MISSING_PARENTS);
292     }
293
294     private void addTerminationPoint(InstanceIdentifier<?> bridgeIid, String portName, int vlanId,
295             Class<? extends InterfaceTypeBase> type, Map<String, String> options, IfTunnel ifTunnel) {
296         OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder();
297
298         tpAugmentationBuilder.setName(portName);
299
300         if (type != null) {
301             tpAugmentationBuilder.setInterfaceType(type);
302         }
303
304         if (options != null) {
305             List<Options> optionsList = new ArrayList<>();
306             for (Map.Entry<String, String> entry : options.entrySet()) {
307                 OptionsBuilder optionsBuilder = new OptionsBuilder();
308                 optionsBuilder.withKey(new OptionsKey(entry.getKey()));
309                 optionsBuilder.setOption(entry.getKey());
310                 optionsBuilder.setValue(entry.getValue());
311                 optionsList.add(optionsBuilder.build());
312             }
313             tpAugmentationBuilder.setOptions(optionsList);
314         }
315
316         if (vlanId != 0) {
317             tpAugmentationBuilder.setVlanMode(OvsdbPortInterfaceAttributes.VlanMode.Access);
318             tpAugmentationBuilder.setVlanTag(new VlanId(vlanId));
319         }
320
321         if (bfdMonitoringEnabled(ifTunnel)) {
322             if (isOfTunnel(ifTunnel)) {
323                 LOG.warn("BFD Monitoring not supported for OFTunnels");
324             } else {
325                 List<InterfaceBfd> bfdParams = getBfdParams(ifTunnel);
326                 tpAugmentationBuilder.setInterfaceBfd(bfdParams);
327             }
328         }
329         TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
330         InstanceIdentifier<TerminationPoint> tpIid = createTerminationPointInstanceIdentifier(
331                 InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(Node.class)), portName);
332         tpBuilder.withKey(InstanceIdentifier.keyOf(tpIid));
333         tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
334
335         batchingUtils.write(tpIid, tpBuilder.build(), BatchingUtils.EntityType.TOPOLOGY_CONFIG);
336     }
337
338     private static List<InterfaceBfd> getBfdParams(IfTunnel ifTunnel) {
339         List<InterfaceBfd> bfdParams = new ArrayList<>();
340         bfdParams.add(
341                 getIfBfdObj(BFD_PARAM_ENABLE, ifTunnel != null ? ifTunnel.isMonitorEnabled().toString() : "false"));
342         bfdParams.add(getIfBfdObj(BFD_PARAM_MIN_TX,
343                 ifTunnel != null && ifTunnel.getMonitorInterval() != null ? ifTunnel.getMonitorInterval().toString()
344                         : BFD_MIN_TX_VAL));
345         bfdParams.add(getIfBfdObj(BFD_PARAM_FORWARDING_IF_RX, BFD_FORWARDING_IF_RX_VAL));
346         return bfdParams;
347     }
348
349     private static InterfaceBfd getIfBfdObj(String key, String value) {
350         InterfaceBfdBuilder bfdBuilder = new InterfaceBfdBuilder();
351         bfdBuilder.setBfdKey(key).withKey(new InterfaceBfdKey(key)).setBfdValue(value);
352         return bfdBuilder.build();
353     }
354
355     private String getSwitchVersion(InstanceIdentifier<Node> bridgeIid) {
356         String ovsNodeId = bridgeIid.firstKeyOf(Node.class).getNodeId().getValue().split("/bridge")[0];
357         return ovsVersionCache.get(ovsNodeId);
358     }
359
360     private String getVersionForBridgeNodeId(String ovsNodeId) {
361         InstanceIdentifier<Node> ovsNodeIid = InstanceIdentifier.create(NetworkTopology.class)
362                 .child(Topology.class, new TopologyKey(IfmConstants.OVSDB_TOPOLOGY_ID))
363                 .child(Node.class, new NodeKey(new NodeId(ovsNodeId)));
364         String ovsVersion = DEFAULT_OVS_VERSION;
365         try {
366             Node ovsNode = singleTxDB.syncRead(LogicalDatastoreType.OPERATIONAL, ovsNodeIid);
367             ovsVersion = ovsNode.augmentation(OvsdbNodeAugmentation.class).getOvsVersion()
368                     .toLowerCase(Locale.ROOT);
369         } catch (ReadFailedException e) {
370             LOG.error("OVS Node {} not present", ovsNodeId);
371         }
372         return ovsVersion;
373     }
374
375     public static InstanceIdentifier<TerminationPoint> createTerminationPointInstanceIdentifier(NodeKey nodekey,
376             String portName) {
377         InstanceIdentifier<TerminationPoint> terminationPointPath = InstanceIdentifier.create(NetworkTopology.class)
378                 .child(Topology.class, new TopologyKey(IfmConstants.OVSDB_TOPOLOGY_ID)).child(Node.class, nodekey)
379                 .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName)));
380
381         LOG.debug("Termination point InstanceIdentifier generated : {}", terminationPointPath);
382         return terminationPointPath;
383     }
384
385     public void removeTerminationEndPoint(InstanceIdentifier<?> bridgeIid, String interfaceName) {
386         LOG.debug("removing termination point for {}", interfaceName);
387         InstanceIdentifier<TerminationPoint> tpIid = SouthboundUtils.createTerminationPointInstanceIdentifier(
388                 InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(Node.class)), interfaceName);
389         batchingUtils.delete(tpIid, BatchingUtils.EntityType.TOPOLOGY_CONFIG);
390     }
391
392     public static boolean ifBfdStatusNotEqual(OvsdbTerminationPointAugmentation tpOld,
393                                            OvsdbTerminationPointAugmentation tpNew) {
394         return (tpNew.getInterfaceBfdStatus() != null
395                 && (tpOld == null || !tpNew.getInterfaceBfdStatus().equals(tpOld.getInterfaceBfdStatus())));
396     }
397
398     public static boolean changeInBfdMonitoringDetected(OvsdbTerminationPointAugmentation tpOld,
399                                                         OvsdbTerminationPointAugmentation tpNew) {
400         if (tpOld != null) {
401             return org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.SouthboundUtils
402                     .bfdMonitoringEnabled(tpNew.getInterfaceBfd())
403                     != org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.SouthboundUtils
404                     .bfdMonitoringEnabled(tpOld.getInterfaceBfd());
405         }
406         return false;
407     }
408
409     public static boolean bfdMonitoringEnabled(IfTunnel ifTunnel) {
410         return ifTunnel.isMonitorEnabled()
411                 && TunnelMonitoringTypeBfd.class.isAssignableFrom(ifTunnel.getMonitorProtocol());
412     }
413
414     public static boolean bfdMonitoringEnabled(List<InterfaceBfd> interfaceBfds) {
415         if (interfaceBfds == null) {
416             return false;
417         }
418         for (InterfaceBfd interfaceBfd : interfaceBfds) {
419             if (SouthboundUtils.BFD_ENABLE_KEY.equalsIgnoreCase(interfaceBfd.getBfdKey())) {
420                 return SouthboundUtils.BFD_ENABLE_VALUE.equalsIgnoreCase(interfaceBfd.getBfdValue());//checkBfdEnabled
421             }
422         }
423         return false;
424     }
425
426     public static boolean isMonitorProtocolBfd(IfTunnel ifTunnel) {
427         return TunnelMonitoringTypeBfd.class.isAssignableFrom(ifTunnel.getMonitorProtocol());
428     }
429
430     @SuppressFBWarnings("DM_DEFAULT_ENCODING")
431     public static String generateOfTunnelName(BigInteger dpId, IfTunnel ifTunnel) {
432         String sourceKey = ifTunnel.getTunnelSource().stringValue();
433         String remoteKey = ifTunnel.getTunnelDestination().stringValue();
434         if (ifTunnel.isTunnelSourceIpFlow() != null) {
435             sourceKey = "flow";
436         }
437         if (ifTunnel.isTunnelRemoteIpFlow() != null) {
438             remoteKey = "flow";
439         }
440         String tunnelNameKey = dpId.toString() + sourceKey + remoteKey;
441         String uuidStr = UUID.nameUUIDFromBytes(tunnelNameKey.getBytes()).toString().substring(0, 12).replace("-", "");
442         return String.format("%s%s", "tun", uuidStr);
443     }
444
445     public static boolean isOfTunnel(IfTunnel ifTunnel) {
446         return Boolean.TRUE.equals(ifTunnel.isTunnelRemoteIpFlow())
447                 || Boolean.TRUE.equals(ifTunnel.isTunnelSourceIpFlow());
448     }
449
450     public static boolean isInterfaceTypeTunnel(Class<? extends InterfaceTypeBase> interfaceType) {
451         return InterfaceTypeGre.class.equals(interfaceType) || InterfaceTypeVxlan.class.equals(interfaceType);
452     }
453
454 }