2 * Copyright © 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.itm.impl;
10 import static java.util.Collections.emptyList;
12 import com.google.common.collect.BiMap;
13 import com.google.common.collect.ImmutableBiMap;
14 import com.google.common.collect.ImmutableMap;
15 import com.google.common.net.InetAddresses;
16 import com.google.common.util.concurrent.FutureCallback;
17 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
18 import java.net.InetAddress;
19 import java.nio.charset.StandardCharsets;
20 import java.util.ArrayList;
21 import java.util.Collection;
22 import java.util.Collections;
23 import java.util.List;
24 import java.util.Objects;
25 import java.util.Optional;
26 import java.util.UUID;
27 import java.util.concurrent.ExecutionException;
28 import org.eclipse.jdt.annotation.NonNull;
29 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
30 import org.opendaylight.genius.infra.Datastore.Configuration;
31 import org.opendaylight.genius.infra.TypedReadWriteTransaction;
32 import org.opendaylight.genius.interfacemanager.globals.IfmConstants;
33 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
34 import org.opendaylight.genius.itm.cache.DPNTEPsInfoCache;
35 import org.opendaylight.genius.itm.confighelpers.HwVtep;
36 import org.opendaylight.genius.itm.confighelpers.ItmTunnelAggregationHelper;
37 import org.opendaylight.genius.itm.globals.ITMConstants;
38 import org.opendaylight.genius.mdsalutil.ActionInfo;
39 import org.opendaylight.genius.mdsalutil.FlowEntity;
40 import org.opendaylight.genius.mdsalutil.InstructionInfo;
41 import org.opendaylight.genius.mdsalutil.MDSALUtil;
42 import org.opendaylight.genius.mdsalutil.MatchInfo;
43 import org.opendaylight.genius.mdsalutil.NwConstants;
44 import org.opendaylight.genius.mdsalutil.actions.ActionPuntToController;
45 import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
46 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
47 import org.opendaylight.genius.mdsalutil.matches.MatchTunnelId;
48 import org.opendaylight.mdsal.binding.api.DataBroker;
49 import org.opendaylight.mdsal.binding.api.ReadTransaction;
50 import org.opendaylight.mdsal.binding.api.WriteTransaction;
51 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
52 import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
53 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev170119.Tunnel;
54 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil;
55 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
56 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder;
57 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
58 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefixBuilder;
59 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType;
60 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
61 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
62 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
63 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
64 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnel;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnelBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefs;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefsBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelMonitoringTypeBase;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeGre;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeLogicalGroup;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeMplsOverGre;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.interfaces._interface.NodeIdentifier;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.interfaces._interface.NodeIdentifierBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.interfaces._interface.NodeIdentifierKey;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.tunnel.optional.params.TunnelOptions;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.tunnel.optional.params.TunnelOptionsBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.tunnel.optional.params.TunnelOptionsKey;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.ItmConfig;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.ExternalTunnelList;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeBase;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeExternal;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeHwvtep;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeInternal;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelList;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelOperStatus;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelsState;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoBuilder;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoKey;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPointsBuilder;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPointsKey;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.tunnel.end.points.TzMembership;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.tunnel.end.points.TzMembershipBuilder;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnel;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnelBuilder;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnelKey;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnel;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnelBuilder;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnelKey;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelList;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelListBuilder;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelListKey;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.state.tunnel.list.DstInfoBuilder;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.state.tunnel.list.SrcInfoBuilder;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.NotHostedTransportZones;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZones;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.not.hosted.transport.zones.TepsInNotHostedTransportZone;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.not.hosted.transport.zones.TepsInNotHostedTransportZoneKey;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZone;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZoneKey;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.Vteps;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
118 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
119 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
120 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
121 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
122 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
123 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
124 import org.opendaylight.yangtools.yang.binding.DataObject;
125 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
126 import org.opendaylight.yangtools.yang.common.Uint64;
127 import org.slf4j.Logger;
128 import org.slf4j.LoggerFactory;
130 public final class ItmUtils {
132 private static final Logger LOG = LoggerFactory.getLogger(ItmUtils.class);
133 private static final String ITM_LLDP_FLOW_ENTRY = "ITM Flow Entry ::" + ITMConstants.LLDP_SERVICE_ID;
134 private static final String TUNNEL = "tun";
135 private static final IpPrefix DUMMY_IP_PREFIX = IpPrefixBuilder.getDefaultInstance(ITMConstants.DUMMY_PREFIX);
136 private static final long DEFAULT_MONITORING_INTERVAL = 100L;
137 public static final ItmCache ITM_CACHE = new ItmCache();
139 public static final ImmutableMap<String, Class<? extends TunnelTypeBase>>
141 new ImmutableMap.Builder<String, Class<? extends TunnelTypeBase>>()
142 .put(ITMConstants.TUNNEL_TYPE_GRE, TunnelTypeGre.class)
143 .put(ITMConstants.TUNNEL_TYPE_MPLSoGRE, TunnelTypeMplsOverGre.class)
144 .put(ITMConstants.TUNNEL_TYPE_VXLAN, TunnelTypeVxlan.class)
147 private static final BiMap<String, Class<? extends TunnelTypeBase>> STRING_CLASS_IMMUTABLE_BI_MAP =
148 ImmutableBiMap.copyOf(TUNNEL_TYPE_MAP);
149 private static final Uint64 COOKIE_ITM_LLD = Uint64.fromLongBits(
150 ITMConstants.COOKIE_ITM.longValue() + ITMConstants.LLDP_SERVICE_ID).intern();
155 public static final FutureCallback<Void> DEFAULT_WRITE_CALLBACK = new FutureCallback<>() {
157 public void onSuccess(Void result) {
158 LOG.debug("Success in Datastore write operation");
162 public void onFailure(Throwable error) {
163 LOG.error("Error in Datastore write operation", error);
168 * Synchronous blocking read from data store.
171 * {@link SingleTransactionDataBroker#syncReadOptional(DataBroker, LogicalDatastoreType, InstanceIdentifier)}
174 @SuppressWarnings("checkstyle:IllegalCatch")
175 public static <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType,
176 InstanceIdentifier<T> path, DataBroker broker) {
177 try (ReadTransaction tx = broker.newReadOnlyTransaction()) {
178 return tx.read(datastoreType, path).get();
179 } catch (InterruptedException | ExecutionException e) {
180 LOG.error("Read failed ", e);
181 return Optional.empty();
187 * Asynchronous non-blocking write to data store.
189 * @deprecated Use {@link ManagedNewTransactionRunner} instead of this.
192 public static <T extends DataObject> void asyncWrite(LogicalDatastoreType datastoreType,
193 InstanceIdentifier<T> path, T data, DataBroker broker,
194 FutureCallback<Void> callback) {
195 WriteTransaction tx = broker.newWriteOnlyTransaction();
196 tx.put(datastoreType, path, data, true);
197 Futures.addCallback(tx.commit(),callback, MoreExecutors.directExecutor());
201 * Asynchronous non-blocking update to data store.
203 * @deprecated Use {@link ManagedNewTransactionRunner} instead of this.
206 public static <T extends DataObject> void asyncUpdate(LogicalDatastoreType datastoreType,
207 InstanceIdentifier<T> path, T data, DataBroker broker,
208 FutureCallback<Void> callback) {
209 WriteTransaction tx = broker.newWriteOnlyTransaction();
210 tx.merge(datastoreType, path, data, true);
211 Futures.addCallback(tx.commit(), callback, MoreExecutors.directExecutor());
215 * Asynchronous non-blocking single delete to data store.
217 * @deprecated Use {@link ManagedNewTransactionRunner} instead of this.
220 public static <T extends DataObject> void asyncDelete(LogicalDatastoreType datastoreType,
221 InstanceIdentifier<T> path, DataBroker broker,
222 FutureCallback<Void> callback) {
223 WriteTransaction tx = broker.newWriteOnlyTransaction();
224 tx.delete(datastoreType, path);
225 Futures.addCallback(tx.commit(), callback, MoreExecutors.directExecutor());
229 * Asynchronous non-blocking bulk delete to data store.
231 * @deprecated Use {@link ManagedNewTransactionRunner} instead of this.
234 public static <T extends DataObject> void asyncBulkRemove(final DataBroker broker,
235 final LogicalDatastoreType datastoreType,
236 List<InstanceIdentifier<T>> pathList,
237 FutureCallback<Void> callback) {
238 if (!pathList.isEmpty()) {
239 WriteTransaction tx = broker.newWriteOnlyTransaction();
240 for (InstanceIdentifier<T> path : pathList) {
241 tx.delete(datastoreType, path);
243 Futures.addCallback(tx.commit(), callback ,MoreExecutors.directExecutor());
247 //ITM cleanup:portname and vlanId are removed, causes change in generated
248 //interface name: This has upgrade impact
249 public static String getInterfaceName(final Uint64 datapathid, final String portName, final Integer vlanId) {
250 return datapathid + ":" + portName + ":" + vlanId;
253 public static String getTrunkInterfaceName(String parentInterfaceName,
254 String localHostName, String remoteHostName, String tunnelType) {
255 String tunnelTypeStr;
256 if (tunnelType.contains("TunnelTypeGre")) {
257 tunnelTypeStr = ITMConstants.TUNNEL_TYPE_GRE;
258 } else if (tunnelType.contains("TunnelTypeLogicalGroup")) {
259 tunnelTypeStr = ITMConstants.TUNNEL_TYPE_LOGICAL_GROUP_VXLAN;
261 tunnelTypeStr = ITMConstants.TUNNEL_TYPE_VXLAN;
263 String trunkInterfaceName = trunkInterfaceName(parentInterfaceName, localHostName, remoteHostName,
265 LOG.trace("trunk interface name is {}", trunkInterfaceName);
266 return TUNNEL + getUniqueIdString(trunkInterfaceName);
269 public static void releaseIdForTrunkInterfaceName(String parentInterfaceName,
270 String localHostName, String remoteHostName, String tunnelType) {
271 String tunnelTypeStr;
272 if (tunnelType.contains("TunnelTypeGre")) {
273 tunnelTypeStr = ITMConstants.TUNNEL_TYPE_GRE;
275 tunnelTypeStr = ITMConstants.TUNNEL_TYPE_VXLAN;
277 if (LOG.isTraceEnabled()) {
278 LOG.trace("Releasing Id for trunkInterface - {}", trunkInterfaceName(parentInterfaceName, localHostName,
279 remoteHostName, tunnelTypeStr));
283 private static String trunkInterfaceName(String parentInterfaceName, String localHostName, String remoteHostName,
285 return parentInterfaceName + ":" + localHostName + ":" + remoteHostName + ":" + tunnelType;
288 public static String getLogicalTunnelGroupName(Uint64 srcDpnId, Uint64 destDpnId) {
289 String groupName = srcDpnId + ":" + destDpnId + ":" + ITMConstants.TUNNEL_TYPE_LOGICAL_GROUP_VXLAN;
290 LOG.trace("logical tunnel group name is {}", groupName);
291 return TUNNEL + getUniqueIdString(groupName);
294 public static InetAddress getInetAddressFromIpAddress(IpAddress ip) {
295 return IetfInetUtil.INSTANCE.inetAddressFor(ip);
298 public static InstanceIdentifier<DPNTEPsInfo> getDpnTepInstance(Uint64 dpIdKey) {
299 return InstanceIdentifier.builder(DpnEndpoints.class).child(DPNTEPsInfo.class, new DPNTEPsInfoKey(dpIdKey))
303 public static DPNTEPsInfo createDPNTepInfo(Uint64 dpId, List<TunnelEndPoints> endpoints) {
304 return new DPNTEPsInfoBuilder().withKey(new DPNTEPsInfoKey(dpId)).setTunnelEndPoints(endpoints).build();
307 public static TunnelEndPoints createTunnelEndPoints(Uint64 dpnId, IpAddress ipAddress, String portName,
308 boolean isOfTunnel, int vlanId, List<TzMembership> zones,
309 Class<? extends TunnelTypeBase> tunnelType,
311 // when Interface Mgr provides support to take in Dpn Id
312 return new TunnelEndPointsBuilder().withKey(new TunnelEndPointsKey(ipAddress, tunnelType))
313 .setTzMembership(zones)
314 .setOptionOfTunnel(isOfTunnel).setInterfaceName(ItmUtils.getInterfaceName(dpnId, portName, vlanId))
315 .setTunnelType(tunnelType)
316 .setOptionTunnelTos(tos)
320 public static TunnelEndPoints createDummyTunnelEndPoints(Uint64 dpnID, IpAddress ipAddress, boolean ofTunnel,
321 String tos, List<TzMembership> zones,
322 Class<? extends TunnelTypeBase> tunnelType,
323 String port, int vlanID) {
325 return ItmUtils.createTunnelEndPoints(dpnID, ipAddress, port, ofTunnel, vlanID, zones,
329 public static InstanceIdentifier<Interface> buildId(String interfaceName) {
330 return InstanceIdentifier.builder(Interfaces.class).child(Interface.class, new InterfaceKey(interfaceName))
334 public static InstanceIdentifier<IfTunnel> buildTunnelId(String ifName) {
335 return InstanceIdentifier.builder(Interfaces.class)
336 .child(Interface.class, new InterfaceKey(ifName)).augmentation(IfTunnel.class).build();
339 public static Interface buildLogicalTunnelInterface(Uint64 dpn, String ifName, String desc, boolean enabled) {
340 InterfaceBuilder builder = new InterfaceBuilder().withKey(new InterfaceKey(ifName)).setName(ifName)
341 .setDescription(desc).setEnabled(enabled).setType(Tunnel.class);
342 ParentRefs parentRefs = new ParentRefsBuilder().setDatapathNodeIdentifier(dpn).build();
343 builder.addAugmentation(ParentRefs.class, parentRefs);
345 IfTunnel tunnel = new IfTunnelBuilder()
346 .setTunnelDestination(IpAddressBuilder.getDefaultInstance(ITMConstants.DUMMY_IP_ADDRESS))
347 .setTunnelSource(IpAddressBuilder.getDefaultInstance(ITMConstants.DUMMY_IP_ADDRESS)).setInternal(true)
348 .setMonitorEnabled(false).setTunnelInterfaceType(TunnelTypeLogicalGroup.class)
349 .setTunnelRemoteIpFlow(false).build();
350 builder.addAugmentation(IfTunnel.class, tunnel);
351 return builder.build();
354 public static Interface buildTunnelInterface(Uint64 dpn, String ifName, String desc, boolean enabled,
355 Class<? extends TunnelTypeBase> tunType, IpAddress localIp,
356 IpAddress remoteIp, boolean internal,
357 Boolean monitorEnabled,
358 Class<? extends TunnelMonitoringTypeBase> monitorProtocol,
359 Integer monitorInterval, boolean useOfTunnel,
360 List<TunnelOptions> tunOptions) {
362 return buildTunnelInterface(dpn, ifName, desc, enabled, tunType, localIp, remoteIp, internal,
363 monitorEnabled, monitorProtocol, monitorInterval, useOfTunnel, null,
367 public static Interface buildTunnelInterface(Uint64 dpn, String ifName, String desc, boolean enabled,
368 Class<? extends TunnelTypeBase> tunType, IpAddress localIp,
369 IpAddress remoteIp, boolean internal,
370 Boolean monitorEnabled,
371 Class<? extends TunnelMonitoringTypeBase> monitorProtocol,
372 Integer monitorInterval, boolean useOfTunnel, String parentIfaceName,
373 List<TunnelOptions> tunnelOptions) {
374 InterfaceBuilder builder = new InterfaceBuilder().withKey(new InterfaceKey(ifName)).setName(ifName)
375 .setDescription(desc).setEnabled(enabled).setType(Tunnel.class);
376 ParentRefs parentRefs =
377 new ParentRefsBuilder().setDatapathNodeIdentifier(dpn).setParentInterface(parentIfaceName).build();
378 builder.addAugmentation(ParentRefs.class, parentRefs);
379 Long monitoringInterval = null;
380 LOG.debug("buildTunnelInterface: monitorProtocol = {} and monitorInterval = {}",
381 monitorProtocol.getName(), monitorInterval);
383 if (monitorInterval != null) {
384 monitoringInterval = monitorInterval.longValue();
387 IfTunnel tunnel = new IfTunnelBuilder().setTunnelDestination(remoteIp)
388 .setTunnelSource(localIp).setTunnelInterfaceType(tunType)
389 .setMonitorEnabled(monitorEnabled).setMonitorProtocol(monitorProtocol)
390 .setMonitorInterval(monitoringInterval).setTunnelRemoteIpFlow(useOfTunnel)
391 .setTunnelOptions(tunnelOptions).setInternal(internal)
393 builder.addAugmentation(IfTunnel.class, tunnel);
394 return builder.build();
397 public static Interface buildHwTunnelInterface(String tunnelIfName, String desc, boolean enabled, String topoId,
398 String nodeId, Class<? extends TunnelTypeBase> tunType,
399 IpAddress srcIp, IpAddress destIp, IpAddress gwIp,
400 Boolean monitorEnabled,
401 Class<? extends TunnelMonitoringTypeBase> monitorProtocol,
402 Integer monitorInterval) {
403 InterfaceBuilder builder = new InterfaceBuilder().withKey(new InterfaceKey(tunnelIfName))
404 .setName(tunnelIfName).setDescription(desc).setEnabled(enabled).setType(Tunnel.class);
405 List<NodeIdentifier> nodeIds = new ArrayList<>();
406 NodeIdentifier hwNode = new NodeIdentifierBuilder().withKey(new NodeIdentifierKey(topoId))
407 .setTopologyId(topoId).setNodeId(nodeId).build();
409 ParentRefs parent = new ParentRefsBuilder().setNodeIdentifier(nodeIds).build();
410 builder.addAugmentation(ParentRefs.class, parent);
411 IfTunnel tunnel = new IfTunnelBuilder().setTunnelDestination(destIp).setTunnelGateway(gwIp)
412 .setTunnelSource(srcIp).setMonitorEnabled(monitorEnabled == null || monitorEnabled)
413 .setMonitorProtocol(monitorProtocol == null ? ITMConstants.DEFAULT_MONITOR_PROTOCOL : monitorProtocol)
414 .setMonitorInterval(DEFAULT_MONITORING_INTERVAL).setTunnelInterfaceType(tunType).setInternal(false)
416 builder.addAugmentation(IfTunnel.class, tunnel);
417 LOG.trace("iftunnel {} built from hwvtep {} ", tunnel, nodeId);
418 return builder.build();
421 public static InternalTunnel buildInternalTunnel(Uint64 srcDpnId, Uint64 dstDpnId,
422 Class<? extends TunnelTypeBase> tunType,
423 String trunkInterfaceName) {
424 return new InternalTunnelBuilder().withKey(new InternalTunnelKey(dstDpnId, srcDpnId, tunType))
425 .setDestinationDPN(dstDpnId)
426 .setSourceDPN(srcDpnId).setTransportType(tunType)
427 .setTunnelInterfaceNames(Collections.singletonList(trunkInterfaceName)).build();
430 public static ExternalTunnel buildExternalTunnel(String srcNode, String dstNode,
431 Class<? extends TunnelTypeBase> tunType,
432 String trunkInterfaceName) {
433 return new ExternalTunnelBuilder().withKey(
434 new ExternalTunnelKey(dstNode, srcNode, tunType))
435 .setSourceDevice(srcNode).setDestinationDevice(dstNode)
436 .setTunnelInterfaceName(trunkInterfaceName)
437 .setTransportType(tunType).build();
440 private static String getUniqueIdString(String idKey) {
441 return UUID.nameUUIDFromBytes(idKey.getBytes(StandardCharsets.UTF_8)).toString().substring(0, 12)
445 public static List<DPNTEPsInfo> getDpnTepListFromDpnId(DPNTEPsInfoCache dpnTEPsInfoCache, List<Uint64> dpnIds) {
446 Collection<DPNTEPsInfo> meshedDpnList = dpnTEPsInfoCache.getAllPresent();
447 List<DPNTEPsInfo> cfgDpnList = new ArrayList<>();
448 for (Uint64 dpnId : dpnIds) {
449 for (DPNTEPsInfo teps : meshedDpnList) {
450 if (dpnId.equals(teps.getDPNID())) {
451 cfgDpnList.add(teps);
459 @SuppressWarnings("checkstyle:IllegalCatch")
460 public static void addTerminatingServiceTable(TypedReadWriteTransaction<Configuration> tx,
461 Uint64 dpnId, IMdsalApiManager mdsalManager) {
462 LOG.trace("Installing PUNT to Controller flow in DPN {} ", dpnId);
463 List<ActionInfo> listActionInfo = new ArrayList<>();
464 listActionInfo.add(new ActionPuntToController());
467 List<MatchInfo> mkMatches = new ArrayList<>();
469 mkMatches.add(new MatchTunnelId(Uint64.valueOf(ITMConstants.LLDP_SERVICE_ID)));
471 List<InstructionInfo> mkInstructions = new ArrayList<>();
472 mkInstructions.add(new InstructionApplyActions(listActionInfo));
474 FlowEntity terminatingServiceTableFlowEntity = MDSALUtil
475 .buildFlowEntity(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE,
476 getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE, ITMConstants.LLDP_SERVICE_ID),
477 5, ITM_LLDP_FLOW_ENTRY, 0, 0,
478 COOKIE_ITM_LLD, mkMatches, mkInstructions);
479 mdsalManager.addFlow(tx, terminatingServiceTableFlowEntity);
480 } catch (Exception e) {
481 LOG.error("Error while setting up Table 36 for {}", dpnId, e);
485 @SuppressWarnings("checkstyle:IllegalCatch")
486 public static void removeTerminatingServiceTable(TypedReadWriteTransaction<Configuration> tx,
487 Uint64 dpnId, IMdsalApiManager mdsalManager) {
488 LOG.trace("Removing PUNT to Controller flow in DPN {} ", dpnId);
491 mdsalManager.removeFlow(tx, dpnId,
492 getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE, ITMConstants.LLDP_SERVICE_ID),
493 NwConstants.INTERNAL_TUNNEL_TABLE);
494 } catch (Exception e) {
495 LOG.error("Error while setting up Table 36 for {}", dpnId, e);
499 private static String getFlowRef(long termSvcTable, int svcId) {
500 return String.valueOf(termSvcTable) + svcId;
503 public static <T> boolean isEmpty(Collection<T> collection) {
504 return collection == null || collection.isEmpty();
507 public static @NonNull HwVtep createHwVtepObject(String topoId, String nodeId, IpAddress ipAddress,
508 Class<? extends TunnelTypeBase> tunneltype,
509 TransportZone transportZone) {
510 HwVtep hwVtep = new HwVtep();
511 hwVtep.setHwIp(ipAddress);
512 hwVtep.setNodeId(nodeId);
513 hwVtep.setTopoId(topoId);
514 hwVtep.setTransportZone(transportZone.getZoneName());
515 hwVtep.setTunnelType(tunneltype);
519 public static String getHwParentIf(String topoId, String srcNodeid) {
520 return topoId + ":" + srcNodeid;
524 * Synchronous blocking write to data store.
527 * {@link SingleTransactionDataBroker#syncWrite(DataBroker, LogicalDatastoreType, InstanceIdentifier, DataObject)}
530 public static <T extends DataObject> void syncWrite(LogicalDatastoreType datastoreType,
531 InstanceIdentifier<T> path, T data, DataBroker broker) {
532 WriteTransaction tx = broker.newWriteOnlyTransaction();
533 tx.put(datastoreType, path, data, true);
536 } catch (InterruptedException | ExecutionException e) {
537 LOG.error("ITMUtils:SyncWrite , Error writing to datastore (path, data) : ({}, {})", path, data);
538 throw new RuntimeException(e.getMessage(), e);
542 public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces
543 .rev140508.interfaces.state.Interface> buildStateInterfaceId(
544 String interfaceName) {
545 return InstanceIdentifier.builder(InterfacesState.class)
546 .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
547 .state.Interface.class,
548 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces
549 .rev140508.interfaces.state.InterfaceKey(
550 interfaceName)).build();
554 public static List<String> getInternalTunnelInterfaces(DataBroker dataBroker) {
555 Collection<String> internalInterfaces = ITM_CACHE.getAllInternalInterfaces();
556 List<String> tunnelList = new ArrayList<>();
557 if (internalInterfaces.isEmpty()) {
558 tunnelList = getAllInternalTunnlInterfacesFromDS(dataBroker);
560 LOG.debug("Internal Interfaces from Cache size: {}", internalInterfaces.size());
561 tunnelList.addAll(internalInterfaces);
563 LOG.trace("ItmUtils Internal TunnelList: {}", tunnelList);
567 public static List<InternalTunnel> getInternalTunnelsFromCache(DataBroker dataBroker) {
568 Collection<InternalTunnel> internalInterfaces = ITM_CACHE.getAllInternalTunnel();
569 LOG.trace("getInternalTunnelsFromCache - List of InternalTunnels in the Cache: {} ", internalInterfaces);
570 List<InternalTunnel> tunnelList = new ArrayList<>();
571 if (internalInterfaces.isEmpty()) {
572 LOG.trace("ItmUtils.getInternalTunnelsFromCache invoking getAllInternalTunnlInterfacesFromDS");
573 tunnelList = getAllInternalTunnels(dataBroker);
575 LOG.debug("No. of Internal Tunnel Interfaces in cache: {} ", internalInterfaces.size());
576 tunnelList.addAll(internalInterfaces);
578 LOG.trace("List of Internal Tunnels: {}", tunnelList);
582 @SuppressFBWarnings("RV_CHECK_FOR_POSITIVE_INDEXOF")
583 public static ExternalTunnelKey getExternalTunnelKey(String dst, String src,
584 Class<? extends TunnelTypeBase> tunType) {
585 final int srcIndex = src.indexOf("physicalswitch");
587 src = src.substring(0, srcIndex - 1);
589 final int dstIndex = dst.indexOf("physicalswitch");
591 dst = dst.substring(0, dstIndex - 1);
593 return new ExternalTunnelKey(dst, src, tunType);
596 public static List<TunnelEndPoints> getTEPsForDpn(Uint64 srcDpn, Collection<DPNTEPsInfo> dpnList) {
597 for (DPNTEPsInfo dpn : dpnList) {
598 if (Objects.equals(dpn.getDPNID(), srcDpn)) {
599 return new ArrayList<>(dpn.nonnullTunnelEndPoints());
605 public static List<InternalTunnel> getAllInternalTunnels(DataBroker dataBroker) {
606 List<InternalTunnel> result = null;
607 InstanceIdentifier<TunnelList> iid = InstanceIdentifier.builder(TunnelList.class).build();
608 Optional<TunnelList> tunnelList = read(LogicalDatastoreType.CONFIGURATION, iid, dataBroker);
610 if (tunnelList.isPresent()) {
611 result = tunnelList.get().getInternalTunnel();
613 if (result == null) {
614 result = emptyList();
619 public static InternalTunnel getInternalTunnel(String interfaceName, DataBroker broker) {
620 InternalTunnel internalTunnel = ITM_CACHE.getInternalTunnel(interfaceName);
621 LOG.trace("ItmUtils getInternalTunnel List of InternalTunnels in the Cache {} ", internalTunnel);
622 if (internalTunnel == null) {
623 internalTunnel = getInternalTunnelFromDS(interfaceName, broker);
625 return internalTunnel;
628 private static List<String> getAllInternalTunnlInterfacesFromDS(DataBroker broker) {
629 List<String> tunnelList = new ArrayList<>();
630 List<InternalTunnel> internalTunnels = getAllInternalTunnels(broker);
631 if (internalTunnels != null) {
632 for (InternalTunnel tunnel : internalTunnels) {
633 List<String> tunnelInterfaceNames = tunnel.getTunnelInterfaceNames();
634 if (tunnelInterfaceNames != null) {
635 for (String tunnelInterfaceName : tunnelInterfaceNames) {
636 tunnelList.add(tunnelInterfaceName);
641 LOG.debug("Internal Tunnel Interfaces list: {} ", tunnelList);
645 private static ExternalTunnel getExternalTunnelFromDS(String interfaceName, DataBroker broker) {
646 List<ExternalTunnel> externalTunnels = getAllExternalTunnels(broker);
647 if (externalTunnels != null) {
648 for (ExternalTunnel tunnel : externalTunnels) {
649 String tunnelInterfaceName = tunnel.getTunnelInterfaceName();
650 if (tunnelInterfaceName != null && tunnelInterfaceName.equalsIgnoreCase(interfaceName)) {
651 LOG.trace("getExternalTunnelFromDS tunnelInterfaceName: {} ", tunnelInterfaceName);
659 public static ExternalTunnel getExternalTunnel(String interfaceName, DataBroker broker) {
660 ExternalTunnel externalTunnel = ITM_CACHE.getExternalTunnel(interfaceName);
661 if (externalTunnel == null) {
662 externalTunnel = getExternalTunnelFromDS(interfaceName, broker);
664 LOG.trace("getExternalTunnel externalTunnel: {} ", externalTunnel);
665 return externalTunnel;
668 private static List<ExternalTunnel> getAllExternalTunnels(DataBroker dataBroker) {
669 List<ExternalTunnel> result = null;
670 InstanceIdentifier<ExternalTunnelList> iid = InstanceIdentifier.builder(ExternalTunnelList.class).build();
671 Optional<ExternalTunnelList> tunnelList = read(LogicalDatastoreType.CONFIGURATION, iid, dataBroker);
672 if (tunnelList.isPresent()) {
673 result = tunnelList.get().getExternalTunnel();
675 if (result == null) {
676 result = emptyList();
681 public static String convertTunnelTypetoString(Class<? extends TunnelTypeBase> tunType) {
682 String tunnelType = ITMConstants.TUNNEL_TYPE_VXLAN;
683 if (tunType.equals(TunnelTypeVxlan.class)) {
684 tunnelType = ITMConstants.TUNNEL_TYPE_VXLAN;
685 } else if (tunType.equals(TunnelTypeGre.class)) {
686 tunnelType = ITMConstants.TUNNEL_TYPE_GRE;
687 } else if (tunType.equals(TunnelTypeMplsOverGre.class)) {
688 tunnelType = ITMConstants.TUNNEL_TYPE_MPLSoGRE;
689 } else if (tunType.equals(TunnelTypeLogicalGroup.class)) {
690 tunnelType = ITMConstants.TUNNEL_TYPE_LOGICAL_GROUP_VXLAN;
696 public static boolean isItmIfType(Class<? extends InterfaceType> ifType) {
697 return ifType != null && ifType.isAssignableFrom(Tunnel.class);
700 public static StateTunnelListKey getTunnelStateKey(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
701 .interfaces.rev140508.interfaces.state.Interface iface) {
702 StateTunnelListKey key = null;
703 if (isItmIfType(iface.getType())) {
704 key = new StateTunnelListKey(iface.getName());
709 public static Interface getInterface(
710 String name, IInterfaceManager ifaceManager) {
711 Interface result = ITM_CACHE.getInterface(name);
712 if (result == null) {
713 result = ifaceManager.getInterfaceInfoFromConfigDataStore(name);
714 if (result != null) {
715 ITM_CACHE.addInterface(result);
721 public static boolean falseIfNull(Boolean value) {
722 return value == null ? false : value;
725 public static <T> List<T> getIntersection(List<T> list1, List<T> list2) {
726 List<T> list = new ArrayList<>();
727 for (T iter : list1) {
728 if (list2.contains(iter)) {
732 LOG.debug(" getIntersection - L1 {}, L2 - {}, Intersection - {}", list1, list2, list);
736 public static void addTransportZoneMembership(List<TzMembership> zones, String zoneName) {
737 zones.add(new TzMembershipBuilder().setZoneName(zoneName).build());
740 public static List<TzMembership> createTransportZoneMembership(String zoneName) {
741 List<TzMembership> zones = new ArrayList<>();
742 zones.add(new TzMembershipBuilder().setZoneName(zoneName).build());
747 * Gets the transport zone in TepsNotHosted list in the Operational Datastore, based on transport zone name.
749 * @param unknownTz transport zone name
750 * @param dataBroker data broker handle to perform read operations on Oper datastore
751 * @return the TepsInNotHostedTransportZone object in the TepsNotHosted list in Oper DS
753 public static TepsInNotHostedTransportZone getUnknownTransportZoneFromITMOperDS(
754 String unknownTz, DataBroker dataBroker) {
755 InstanceIdentifier<TepsInNotHostedTransportZone> unknownTzPath =
756 InstanceIdentifier.builder(NotHostedTransportZones.class)
757 .child(TepsInNotHostedTransportZone.class,
758 new TepsInNotHostedTransportZoneKey(unknownTz)).build();
759 Optional<TepsInNotHostedTransportZone> unknownTzOptional =
760 ItmUtils.read(LogicalDatastoreType.OPERATIONAL, unknownTzPath, dataBroker);
761 if (unknownTzOptional.isPresent()) {
762 return unknownTzOptional.get();
768 * Gets the bridge datapath ID from Network topology Node's OvsdbBridgeAugmentation, in the Operational DS.
770 * @param node Network Topology Node
771 * @param bridge bridge name
772 * @param dataBroker data broker handle to perform operations on datastore
773 * @return the datapath ID of bridge in string form
775 public static String getBridgeDpid(Node node, String bridge, DataBroker dataBroker) {
776 OvsdbBridgeAugmentation ovsdbBridgeAugmentation = null;
777 Node bridgeNode = null;
778 String datapathId = null;
780 NodeId ovsdbNodeId = node.key().getNodeId();
782 NodeId brNodeId = new NodeId(ovsdbNodeId.getValue()
783 + "/" + ITMConstants.BRIDGE_URI_PREFIX + "/" + bridge);
785 InstanceIdentifier<Node> bridgeIid =
787 .create(NetworkTopology.class)
788 .child(Topology.class, new TopologyKey(IfmConstants.OVSDB_TOPOLOGY_ID))
789 .child(Node.class, new NodeKey(brNodeId));
791 Optional<Node> opBridgeNode = ItmUtils.read(LogicalDatastoreType.OPERATIONAL, bridgeIid, dataBroker);
793 if (opBridgeNode.isPresent()) {
794 bridgeNode = opBridgeNode.get();
796 if (bridgeNode != null) {
797 ovsdbBridgeAugmentation = bridgeNode.augmentation(OvsdbBridgeAugmentation.class);
800 if (ovsdbBridgeAugmentation != null && ovsdbBridgeAugmentation.getDatapathId() != null) {
801 datapathId = ovsdbBridgeAugmentation.getDatapathId().getValue();
807 * Gets the Network topology Node from Operational Datastore
808 * based on Bridge Augmentation.
810 * @param bridgeAugmentation bridge augmentation of OVSDB node
811 * @param dataBroker data broker handle to perform operations on datastore
812 * @return the Network Topology Node i.e. OVSDB node which is managing the specified bridge
814 public static Node getOvsdbNode(OvsdbBridgeAugmentation bridgeAugmentation,
815 DataBroker dataBroker) {
816 Node ovsdbNode = null;
817 Optional<Node> opOvsdbNode = Optional.empty();
818 if (bridgeAugmentation != null) {
819 InstanceIdentifier<Node> ovsdbNodeIid =
820 (InstanceIdentifier<Node>) bridgeAugmentation.getManagedBy().getValue();
821 opOvsdbNode = ItmUtils.read(LogicalDatastoreType.OPERATIONAL, ovsdbNodeIid, dataBroker);
823 if (opOvsdbNode.isPresent()) {
824 ovsdbNode = opOvsdbNode.get();
830 * Gets the bridge datapath ID in string form from
831 * Network topology Node's OvsdbBridgeAugmentation in the Operational DS.
833 * @param augmentedNode Ovsdb Augmented Network Topology Node
834 * @return the datapath ID of bridge in string form
836 public static String getStrDatapathId(OvsdbBridgeAugmentation augmentedNode) {
837 String datapathId = null;
838 if (augmentedNode != null && augmentedNode.getDatapathId() != null) {
839 datapathId = augmentedNode.getDatapathId().getValue();
845 * Returns the dummy subnet (255.255.255.255/32) as IpPrefix object.
847 * @return the dummy subnet (255.255.255.255/32) in IpPrefix object
849 public static IpPrefix getDummySubnet() {
850 return DUMMY_IP_PREFIX;
854 * Deletes the transport zone from Configuration datastore.
856 * @param tzName transport zone name
857 * @param dataBroker data broker handle to perform operations on datastore
859 public static void deleteTransportZoneFromConfigDS(String tzName, DataBroker dataBroker) {
860 // check whether transport-zone exists in config DS.
861 TransportZone transportZoneFromConfigDS = ItmUtils.getTransportZoneFromConfigDS(tzName, dataBroker);
862 if (transportZoneFromConfigDS != null) {
863 // it exists, delete default-TZ now
864 InstanceIdentifier<TransportZone> path = InstanceIdentifier.builder(TransportZones.class)
865 .child(TransportZone.class, new TransportZoneKey(tzName)).build();
866 LOG.debug("Removing {} transport-zone from config DS.", tzName);
868 SingleTransactionDataBroker.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, path);
869 } catch (TransactionCommitFailedException e) {
870 LOG.error("deleteTransportZoneFromConfigDS failed. {} could not be deleted.", tzName, e);
876 * Validates the tunnelType argument and returnsTunnelTypeBase class object
877 * corresponding to tunnelType obtained in String format.
879 * @param tunnelType type of tunnel in string form
880 * @return tunnel-type in TunnelTypeBase object
882 public static Class<? extends TunnelTypeBase> getTunnelType(String tunnelType) {
883 // validate tunnelType string, in case it is NULL or empty, then
884 // take VXLAN tunnel type by default
885 if (tunnelType == null || tunnelType.isEmpty()) {
886 return TUNNEL_TYPE_MAP.get(ITMConstants.TUNNEL_TYPE_VXLAN);
887 } else if (!tunnelType.equals(ITMConstants.TUNNEL_TYPE_VXLAN)
888 && !tunnelType.equals(ITMConstants.TUNNEL_TYPE_GRE)) {
889 // if tunnel type is some incorrect value, then
890 // take VXLAN tunnel type by default
891 return TUNNEL_TYPE_MAP.get(ITMConstants.TUNNEL_TYPE_VXLAN);
894 // return TunnelTypeBase object corresponding to tunnel-type
895 return TUNNEL_TYPE_MAP.get(tunnelType);
898 public static List<TzMembership> removeTransportZoneMembership(TunnelEndPoints endPts, List<TzMembership> zones) {
899 LOG.trace(" RemoveTransportZoneMembership TEPs {}, Membership to be removed {} ", endPts, zones);
900 List<TzMembership> existingTzList = new ArrayList<>(endPts.nonnullTzMembership());
901 for (TzMembership membership : zones) {
902 existingTzList.remove(new TzMembershipBuilder().setZoneName(membership.getZoneName()).build());
904 LOG.debug("Modified Membership List {}", existingTzList);
905 return existingTzList;
909 public static List<TzMembership> getOriginalTzMembership(TunnelEndPoints srcTep, Uint64 dpnId,
910 Collection<DPNTEPsInfo> meshedDpnList) {
911 LOG.trace("Original Membership for source DPN {}, source TEP {}", dpnId, srcTep);
912 for (DPNTEPsInfo dstDpn : meshedDpnList) {
913 if (dpnId.equals(dstDpn.getDPNID())) {
914 for (TunnelEndPoints tep : dstDpn.nonnullTunnelEndPoints()) {
915 if (Objects.equals(tep.getIpAddress(), srcTep.getIpAddress())) {
916 List<TzMembership> tzMemberships = tep.nonnullTzMembership();
917 LOG.debug("Original Membership size {}", tzMemberships.size());
918 return tzMemberships;
926 public static StateTunnelList buildStateTunnelList(StateTunnelListKey tlKey, String name, boolean state,
927 TunnelOperStatus tunOpStatus, IInterfaceManager ifaceManager,
929 StateTunnelListBuilder stlBuilder = new StateTunnelListBuilder();
930 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface =
931 ItmUtils.getInterface(name, ifaceManager);
932 IfTunnel ifTunnel = iface.augmentation(IfTunnel.class);
933 ParentRefs parentRefs = iface.augmentation(ParentRefs.class);
934 if (ifTunnel == null || parentRefs == null) {
937 DstInfoBuilder dstInfoBuilder = new DstInfoBuilder();
938 SrcInfoBuilder srcInfoBuilder = new SrcInfoBuilder();
939 dstInfoBuilder.setTepIp(ifTunnel.getTunnelDestination());
940 srcInfoBuilder.setTepIp(ifTunnel.getTunnelSource());
941 // TODO: Add/Improve logic for device type
942 InternalTunnel internalTunnel = ItmUtils.ITM_CACHE.getInternalTunnel(name);
943 ExternalTunnel externalTunnel = ItmUtils.ITM_CACHE.getExternalTunnel(name);
944 if (internalTunnel == null && externalTunnel == null) {
945 // both not present in cache. let us update and try again.
946 internalTunnel = getInternalTunnel(name, broker);
947 externalTunnel = getExternalTunnel(name, broker);
949 if (internalTunnel != null) {
950 srcInfoBuilder.setTepDeviceId(internalTunnel.getSourceDPN().toString())
951 .setTepDeviceType(TepTypeInternal.class);
952 dstInfoBuilder.setTepDeviceId(internalTunnel.getDestinationDPN().toString())
953 .setTepDeviceType(TepTypeInternal.class);
954 stlBuilder.setTransportType(internalTunnel.getTransportType());
955 } else if (externalTunnel != null) {
956 ExternalTunnel tunnel = ItmUtils.ITM_CACHE.getExternalTunnel(name);
957 srcInfoBuilder.setTepDeviceId(tunnel.getSourceDevice())
958 .setTepDeviceType(getDeviceType(tunnel.getSourceDevice()));
959 dstInfoBuilder.setTepDeviceId(tunnel.getDestinationDevice())
960 .setTepDeviceType(getDeviceType(tunnel.getDestinationDevice()))
961 .setTepIp(ifTunnel.getTunnelDestination());
962 stlBuilder.setTransportType(tunnel.getTransportType());
964 stlBuilder.withKey(tlKey).setTunnelInterfaceName(name).setOperState(tunOpStatus).setTunnelState(state)
965 .setDstInfo(dstInfoBuilder.build()).setSrcInfo(srcInfoBuilder.build());
966 return stlBuilder.build();
969 private static Class<? extends TepTypeBase> getDeviceType(String device) {
970 if (device.startsWith("hwvtep")) {
971 return TepTypeHwvtep.class;
972 } else if (InetAddresses.isInetAddress(device)) {
973 // In case of external tunnel, destination-device will be of IP address type.
974 return TepTypeExternal.class;
976 return TepTypeInternal.class;
980 public static InstanceIdentifier<StateTunnelList> buildStateTunnelListId(StateTunnelListKey tlKey) {
981 return InstanceIdentifier.builder(TunnelsState.class).child(StateTunnelList.class, tlKey).build();
985 public static Optional<InternalTunnel> getInternalTunnelFromDS(Uint64 srcDpn, Uint64 destDpn,
986 Class<? extends TunnelTypeBase> type,
987 DataBroker dataBroker) {
988 InstanceIdentifier<InternalTunnel> pathLogicTunnel = InstanceIdentifier.create(TunnelList.class)
989 .child(InternalTunnel.class,
990 new InternalTunnelKey(destDpn, srcDpn, type));
991 //TODO: need to be replaced by cached copy
992 return ItmUtils.read(LogicalDatastoreType.CONFIGURATION, pathLogicTunnel, dataBroker);
995 private static InternalTunnel getInternalTunnelFromDS(String interfaceName, DataBroker broker) {
996 List<InternalTunnel> internalTunnels = getAllInternalTunnels(broker);
997 if (internalTunnels != null) {
998 for (InternalTunnel tunnel : internalTunnels) {
999 List<String> tunnelInterfaceNames = tunnel.getTunnelInterfaceNames();
1000 if (tunnelInterfaceNames != null) {
1001 for (String tunnelInterfaceName : tunnelInterfaceNames) {
1002 if (tunnelInterfaceName.equalsIgnoreCase(interfaceName)) {
1003 LOG.trace("ItmUtils getInternalTunnelFromDS {} ", tunnelInterfaceName);
1013 public static boolean isTunnelAggregationUsed(Class<? extends TunnelTypeBase> tunType) {
1014 return ItmTunnelAggregationHelper.isTunnelAggregationEnabled()
1015 && (tunType.isAssignableFrom(TunnelTypeVxlan.class)
1016 || tunType.isAssignableFrom(TunnelTypeLogicalGroup.class));
1019 public static List<TunnelOptions> buildTunnelOptions(TunnelEndPoints tep, ItmConfig itmConfig) {
1020 List<TunnelOptions> tunOptions = new ArrayList<>();
1022 String tos = tep.getOptionTunnelTos();
1024 tos = itmConfig.getDefaultTunnelTos();
1026 /* populate tos option only if its not default value of 0 */
1027 if (tos != null && !tos.equals("0")) {
1028 TunnelOptionsBuilder optionsBuilder = new TunnelOptionsBuilder();
1029 optionsBuilder.withKey(new TunnelOptionsKey("tos"));
1030 optionsBuilder.setTunnelOption("tos");
1031 optionsBuilder.setValue(tos);
1032 tunOptions.add(optionsBuilder.build());
1035 if (tep.getTunnelType() == TunnelTypeVxlan.class && itmConfig.isGpeExtensionEnabled()) {
1036 TunnelOptionsBuilder optionsBuilder = new TunnelOptionsBuilder();
1037 optionsBuilder.withKey(new TunnelOptionsKey("exts"));
1038 optionsBuilder.setTunnelOption("exts");
1039 optionsBuilder.setValue("gpe");
1040 tunOptions.add(optionsBuilder.build());
1042 return tunOptions.isEmpty() ? null : tunOptions;
1045 public static ExternalTunnel getExternalTunnelbyExternalTunnelKey(ExternalTunnelKey externalTunnelKey,
1046 InstanceIdentifier<ExternalTunnel> path,
1047 DataBroker dataBroker) {
1048 ExternalTunnel exTunnel = ITM_CACHE.getExternalTunnelKeyToExternalTunnels().get(externalTunnelKey);
1049 if (exTunnel == null) {
1050 Optional<ExternalTunnel> ext = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
1051 if (ext.isPresent()) {
1052 exTunnel = ext.get();
1058 public static List<DPNTEPsInfo> getDpnTEPsInfos(DataBroker dataBroker) {
1059 InstanceIdentifier<DpnEndpoints> iid = InstanceIdentifier.builder(DpnEndpoints.class).build();
1060 Optional<DpnEndpoints> dpnEndpoints = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, iid, dataBroker);
1061 if (dpnEndpoints.isPresent()) {
1062 return new ArrayList<>(dpnEndpoints.get().getDPNTEPsInfo());
1064 return new ArrayList<>();
1068 public static InstanceIdentifier<TransportZone> getTZInstanceIdentifier(String tzName) {
1069 return InstanceIdentifier.builder(TransportZones.class).child(TransportZone.class,
1070 new TransportZoneKey(tzName)).build();
1074 * Returns the transport zone from Configuration datastore.
1076 * @param tzName transport zone name
1077 * @param dataBroker data broker handle to perform operations on datastore
1078 * @return the TransportZone object in Config DS
1080 // FIXME: Better is to implement cache to avoid datastore read.
1081 public static TransportZone getTransportZoneFromConfigDS(String tzName, DataBroker dataBroker) {
1082 InstanceIdentifier<TransportZone> tzonePath = getTZInstanceIdentifier(tzName);
1083 Optional<TransportZone> transportZoneOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, tzonePath,
1085 if (transportZoneOptional.isPresent()) {
1086 return transportZoneOptional.get();
1091 public static Class<? extends TunnelTypeBase> convertStringToTunnelType(String tunnelType) {
1092 Class<? extends TunnelTypeBase> tunType = TunnelTypeVxlan.class;
1093 if (STRING_CLASS_IMMUTABLE_BI_MAP.containsKey(tunnelType)) {
1094 tunType = STRING_CLASS_IMMUTABLE_BI_MAP.get(tunnelType);
1099 public static List<Uint64> getDpIdFromTransportzone(DataBroker dataBroker, String tzone) {
1100 List<Uint64> listOfDpId = new ArrayList<>();
1101 InstanceIdentifier<TransportZone> path = InstanceIdentifier.builder(TransportZones.class)
1102 .child(TransportZone.class, new TransportZoneKey(tzone)).build();
1103 Optional<TransportZone> transportZoneOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
1105 if (transportZoneOptional.isPresent()) {
1106 TransportZone transportZone = transportZoneOptional.get();
1107 if (transportZone.getVteps() != null && !transportZone.getVteps().isEmpty()) {
1108 List<Vteps> vtepsList = transportZone.getVteps();
1109 if (vtepsList != null && !vtepsList.isEmpty()) {
1110 for (Vteps vtep : vtepsList) {
1111 listOfDpId.add(vtep.getDpnId());