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.emptyMap;
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.HashMap;
24 import java.util.List;
26 import java.util.Objects;
27 import java.util.Optional;
28 import java.util.UUID;
29 import java.util.concurrent.ExecutionException;
30 import org.eclipse.jdt.annotation.NonNull;
31 import org.eclipse.jdt.annotation.Nullable;
32 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
33 import org.opendaylight.genius.interfacemanager.globals.IfmConstants;
34 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
35 import org.opendaylight.genius.itm.cache.DPNTEPsInfoCache;
36 import org.opendaylight.genius.itm.confighelpers.HwVtep;
37 import org.opendaylight.genius.itm.confighelpers.ItmTunnelAggregationHelper;
38 import org.opendaylight.genius.itm.globals.ITMConstants;
39 import org.opendaylight.genius.mdsalutil.ActionInfo;
40 import org.opendaylight.genius.mdsalutil.FlowEntity;
41 import org.opendaylight.genius.mdsalutil.InstructionInfo;
42 import org.opendaylight.genius.mdsalutil.MDSALUtil;
43 import org.opendaylight.genius.mdsalutil.MatchInfo;
44 import org.opendaylight.genius.mdsalutil.NwConstants;
45 import org.opendaylight.genius.mdsalutil.actions.ActionPuntToController;
46 import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
47 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
48 import org.opendaylight.genius.mdsalutil.matches.MatchTunnelId;
49 import org.opendaylight.mdsal.binding.api.DataBroker;
50 import org.opendaylight.mdsal.binding.api.ReadTransaction;
51 import org.opendaylight.mdsal.binding.api.WriteTransaction;
52 import org.opendaylight.mdsal.binding.util.Datastore.Configuration;
53 import org.opendaylight.mdsal.binding.util.TypedReadWriteTransaction;
54 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
55 import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
56 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev170119.Tunnel;
57 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil;
58 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
59 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder;
60 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
61 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefixBuilder;
62 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType;
63 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
64 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
65 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
66 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
67 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnel;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnelBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefs;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefsBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelMonitoringTypeBase;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeGre;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeLogicalGroup;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeMplsOverGre;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.interfaces._interface.NodeIdentifier;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.interfaces._interface.NodeIdentifierBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.interfaces._interface.NodeIdentifierKey;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.tunnel.optional.params.TunnelOptions;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.tunnel.optional.params.TunnelOptionsBuilder;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.tunnel.optional.params.TunnelOptionsKey;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.ItmConfig;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.ExternalTunnelList;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.OfTepsState;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeBase;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeExternal;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeHwvtep;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeInternal;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelList;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelOperStatus;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelsState;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoBuilder;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoKey;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPointsBuilder;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPointsKey;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.tunnel.end.points.TzMembership;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.tunnel.end.points.TzMembershipBuilder;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.tunnel.end.points.TzMembershipKey;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.tep.config.OfDpnTep;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.tep.config.OfDpnTepBuilder;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.tep.config.OfDpnTepKey;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnel;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnelBuilder;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnelKey;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.of.teps.state.OfTep;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.of.teps.state.OfTepKey;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnel;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnelBuilder;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnelKey;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelList;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelListBuilder;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelListKey;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.state.tunnel.list.DstInfoBuilder;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.state.tunnel.list.SrcInfoBuilder;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.NotHostedTransportZones;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZones;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.not.hosted.transport.zones.TepsInNotHostedTransportZone;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.not.hosted.transport.zones.TepsInNotHostedTransportZoneKey;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZone;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZoneKey;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.Vteps;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.VtepsKey;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
129 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
130 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
131 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
132 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
133 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
134 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
135 import org.opendaylight.yangtools.yang.binding.DataObject;
136 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
137 import org.opendaylight.yangtools.yang.common.Uint64;
138 import org.slf4j.Logger;
139 import org.slf4j.LoggerFactory;
141 public final class ItmUtils {
143 private static final Logger LOG = LoggerFactory.getLogger(ItmUtils.class);
144 private static final String ITM_LLDP_FLOW_ENTRY = "ITM Flow Entry ::" + ITMConstants.LLDP_SERVICE_ID;
145 private static final String TUNNEL = "tun";
146 private static final IpPrefix DUMMY_IP_PREFIX = IpPrefixBuilder.getDefaultInstance(ITMConstants.DUMMY_PREFIX);
147 private static final long DEFAULT_MONITORING_INTERVAL = 100L;
148 public static final ItmCache ITM_CACHE = new ItmCache();
150 public static final ImmutableMap<String, Class<? extends TunnelTypeBase>>
152 new ImmutableMap.Builder<String, Class<? extends TunnelTypeBase>>()
153 .put(ITMConstants.TUNNEL_TYPE_GRE, TunnelTypeGre.class)
154 .put(ITMConstants.TUNNEL_TYPE_MPLSoGRE, TunnelTypeMplsOverGre.class)
155 .put(ITMConstants.TUNNEL_TYPE_VXLAN, TunnelTypeVxlan.class)
158 private static final BiMap<String, Class<? extends TunnelTypeBase>> STRING_CLASS_IMMUTABLE_BI_MAP =
159 ImmutableBiMap.copyOf(TUNNEL_TYPE_MAP);
160 private static final Uint64 COOKIE_ITM_LLD = Uint64.fromLongBits(
161 ITMConstants.COOKIE_ITM.longValue() + ITMConstants.LLDP_SERVICE_ID).intern();
166 public static final FutureCallback<Object> DEFAULT_WRITE_CALLBACK = new FutureCallback<>() {
168 public void onSuccess(Object result) {
169 LOG.debug("Success in Datastore write operation");
173 public void onFailure(Throwable error) {
174 LOG.error("Error in Datastore write operation", error);
179 * Synchronous blocking read from data store.
182 * {@link SingleTransactionDataBroker#syncReadOptional(DataBroker, LogicalDatastoreType, InstanceIdentifier)}
185 @SuppressWarnings("checkstyle:IllegalCatch")
186 public static <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType,
187 InstanceIdentifier<T> path, DataBroker broker) {
188 try (ReadTransaction tx = broker.newReadOnlyTransaction()) {
189 return tx.read(datastoreType, path).get();
190 } catch (InterruptedException | ExecutionException e) {
191 LOG.error("Read failed ", e);
192 return Optional.empty();
196 //ITM cleanup:portname and vlanId are removed, causes change in generated
197 //interface name: This has upgrade impact
199 public static String getInterfaceName(final Uint64 datapathid, final String portName, final Integer vlanId) {
200 return datapathid + ":" + portName + ":" + vlanId;
203 public static String getTrunkInterfaceName(String parentInterfaceName,
204 String localHostName, String remoteHostName, String tunnelType) {
205 String tunnelTypeStr;
206 if (tunnelType.contains("TunnelTypeGre")) {
207 tunnelTypeStr = ITMConstants.TUNNEL_TYPE_GRE;
208 } else if (tunnelType.contains("TunnelTypeLogicalGroup")) {
209 tunnelTypeStr = ITMConstants.TUNNEL_TYPE_LOGICAL_GROUP_VXLAN;
211 tunnelTypeStr = ITMConstants.TUNNEL_TYPE_VXLAN;
213 String trunkInterfaceName = trunkInterfaceName(parentInterfaceName, localHostName, remoteHostName,
215 LOG.trace("trunk interface name is {}", trunkInterfaceName);
216 return TUNNEL + getUniqueIdString(trunkInterfaceName);
219 public static void releaseIdForTrunkInterfaceName(String parentInterfaceName,
220 String localHostName, String remoteHostName, String tunnelType) {
221 String tunnelTypeStr;
222 if (tunnelType.contains("TunnelTypeGre")) {
223 tunnelTypeStr = ITMConstants.TUNNEL_TYPE_GRE;
225 tunnelTypeStr = ITMConstants.TUNNEL_TYPE_VXLAN;
227 if (LOG.isTraceEnabled()) {
228 LOG.trace("Releasing Id for trunkInterface - {}", trunkInterfaceName(parentInterfaceName, localHostName,
229 remoteHostName, tunnelTypeStr));
233 private static String trunkInterfaceName(String parentInterfaceName, String localHostName, String remoteHostName,
235 return parentInterfaceName + ":" + localHostName + ":" + remoteHostName + ":" + tunnelType;
238 public static String getLogicalTunnelGroupName(Uint64 srcDpnId, Uint64 destDpnId) {
239 String groupName = srcDpnId + ":" + destDpnId + ":" + ITMConstants.TUNNEL_TYPE_LOGICAL_GROUP_VXLAN;
240 LOG.trace("logical tunnel group name is {}", groupName);
241 return TUNNEL + getUniqueIdString(groupName);
244 public static InetAddress getInetAddressFromIpAddress(IpAddress ip) {
245 return IetfInetUtil.INSTANCE.inetAddressFor(ip);
248 public static InstanceIdentifier<DPNTEPsInfo> getDpnTepInstance(Uint64 dpIdKey) {
249 return InstanceIdentifier.builder(DpnEndpoints.class).child(DPNTEPsInfo.class, new DPNTEPsInfoKey(dpIdKey))
253 public static DPNTEPsInfo createDPNTepInfo(Uint64 dpId, List<TunnelEndPoints> endpoints) {
254 return new DPNTEPsInfoBuilder().withKey(new DPNTEPsInfoKey(dpId)).setTunnelEndPoints(endpoints).build();
257 public static TunnelEndPoints createTunnelEndPoints(Uint64 dpnId, IpAddress ipAddress, String portName,
258 boolean isOfTunnel, int vlanId, List<TzMembership> zones,
259 Class<? extends TunnelTypeBase> tunnelType,
261 // when Interface Mgr provides support to take in Dpn Id
262 return new TunnelEndPointsBuilder().withKey(new TunnelEndPointsKey(ipAddress, tunnelType))
263 .setTzMembership(zones)
264 .setOptionOfTunnel(isOfTunnel).setInterfaceName(ItmUtils.getInterfaceName(dpnId, portName, vlanId))
265 .setTunnelType(tunnelType)
266 .setOptionTunnelTos(tos)
270 public static TunnelEndPoints createDummyTunnelEndPoints(Uint64 dpnID, IpAddress ipAddress, boolean ofTunnel,
271 String tos, List<TzMembership> zones,
272 Class<? extends TunnelTypeBase> tunnelType,
273 String port, int vlanID) {
275 return ItmUtils.createTunnelEndPoints(dpnID, ipAddress, port, ofTunnel, vlanID, zones,
279 public static InstanceIdentifier<Interface> buildId(String interfaceName) {
280 return InstanceIdentifier.builder(Interfaces.class).child(Interface.class, new InterfaceKey(interfaceName))
284 public static InstanceIdentifier<IfTunnel> buildTunnelId(String ifName) {
285 return InstanceIdentifier.builder(Interfaces.class)
286 .child(Interface.class, new InterfaceKey(ifName)).augmentation(IfTunnel.class).build();
289 public static Interface buildLogicalTunnelInterface(Uint64 dpn, String ifName, String desc, boolean enabled) {
290 return new InterfaceBuilder().withKey(new InterfaceKey(ifName)).setName(ifName)
291 .setDescription(desc).setEnabled(enabled).setType(Tunnel.class)
292 .addAugmentation(new ParentRefsBuilder().setDatapathNodeIdentifier(dpn).build())
293 .addAugmentation(new IfTunnelBuilder()
294 .setTunnelDestination(IpAddressBuilder.getDefaultInstance(ITMConstants.DUMMY_IP_ADDRESS))
295 .setTunnelSource(IpAddressBuilder.getDefaultInstance(ITMConstants.DUMMY_IP_ADDRESS))
296 .setInternal(true).setMonitorEnabled(false).setTunnelInterfaceType(TunnelTypeLogicalGroup.class)
297 .setTunnelRemoteIpFlow(false)
302 public static Interface buildTunnelInterface(Uint64 dpn, String ifName, String desc, boolean enabled,
303 Class<? extends TunnelTypeBase> tunType, IpAddress localIp,
304 IpAddress remoteIp, boolean internal,
305 Boolean monitorEnabled,
306 Class<? extends TunnelMonitoringTypeBase> monitorProtocol,
307 Integer monitorInterval, boolean useOfTunnel,
308 List<TunnelOptions> tunOptions) {
310 return buildTunnelInterface(dpn, ifName, desc, enabled, tunType, localIp, remoteIp, internal,
311 monitorEnabled, monitorProtocol, monitorInterval, useOfTunnel, null,
315 public static Interface buildTunnelInterface(Uint64 dpn, String ifName, String desc, boolean enabled,
316 Class<? extends TunnelTypeBase> tunType, IpAddress localIp,
317 IpAddress remoteIp, boolean internal,
318 Boolean monitorEnabled,
319 Class<? extends TunnelMonitoringTypeBase> monitorProtocol,
320 Integer monitorInterval, boolean useOfTunnel, String parentIfaceName,
321 List<TunnelOptions> tunnelOptions) {
322 InterfaceBuilder builder = new InterfaceBuilder().withKey(new InterfaceKey(ifName)).setName(ifName)
323 .setDescription(desc).setEnabled(enabled).setType(Tunnel.class);
324 builder.addAugmentation(new ParentRefsBuilder()
325 .setDatapathNodeIdentifier(dpn)
326 .setParentInterface(parentIfaceName)
328 Long monitoringInterval = null;
329 LOG.debug("buildTunnelInterface: monitorProtocol = {} and monitorInterval = {}",
330 monitorProtocol.getName(), monitorInterval);
332 if (monitorInterval != null) {
333 monitoringInterval = monitorInterval.longValue();
336 return builder.addAugmentation(new IfTunnelBuilder()
337 .setTunnelDestination(remoteIp).setTunnelSource(localIp).setTunnelInterfaceType(tunType)
338 .setMonitorEnabled(monitorEnabled).setMonitorProtocol(monitorProtocol)
339 .setMonitorInterval(monitoringInterval).setTunnelRemoteIpFlow(useOfTunnel)
340 .setTunnelOptions(tunnelOptions).setInternal(internal)
345 public static Interface buildHwTunnelInterface(String tunnelIfName, String desc, boolean enabled, String topoId,
346 String nodeId, Class<? extends TunnelTypeBase> tunType,
347 IpAddress srcIp, IpAddress destIp, IpAddress gwIp,
348 Boolean monitorEnabled,
349 Class<? extends TunnelMonitoringTypeBase> monitorProtocol,
350 Integer monitorInterval) {
351 InterfaceBuilder builder = new InterfaceBuilder().withKey(new InterfaceKey(tunnelIfName))
352 .setName(tunnelIfName).setDescription(desc).setEnabled(enabled).setType(Tunnel.class);
353 List<NodeIdentifier> nodeIds = new ArrayList<>();
354 NodeIdentifier hwNode = new NodeIdentifierBuilder().withKey(new NodeIdentifierKey(topoId))
355 .setTopologyId(topoId).setNodeId(nodeId).build();
357 builder.addAugmentation(new ParentRefsBuilder().setNodeIdentifier(nodeIds).build());
358 IfTunnel tunnel = new IfTunnelBuilder().setTunnelDestination(destIp).setTunnelGateway(gwIp)
359 .setTunnelSource(srcIp).setMonitorEnabled(monitorEnabled == null || monitorEnabled)
360 .setMonitorProtocol(monitorProtocol == null ? ITMConstants.DEFAULT_MONITOR_PROTOCOL : monitorProtocol)
361 .setMonitorInterval(DEFAULT_MONITORING_INTERVAL).setTunnelInterfaceType(tunType).setInternal(false)
363 builder.addAugmentation(tunnel);
364 LOG.trace("iftunnel {} built from hwvtep {} ", tunnel, nodeId);
365 return builder.build();
368 public static InternalTunnel buildInternalTunnel(Uint64 srcDpnId, Uint64 dstDpnId,
369 Class<? extends TunnelTypeBase> tunType,
370 String trunkInterfaceName) {
371 return new InternalTunnelBuilder().withKey(new InternalTunnelKey(dstDpnId, srcDpnId, tunType))
372 .setDestinationDPN(dstDpnId)
373 .setSourceDPN(srcDpnId).setTransportType(tunType)
374 .setTunnelInterfaceNames(Collections.singletonList(trunkInterfaceName)).build();
377 public static ExternalTunnel buildExternalTunnel(String srcNode, String dstNode,
378 Class<? extends TunnelTypeBase> tunType,
379 String trunkInterfaceName) {
380 return new ExternalTunnelBuilder().withKey(
381 new ExternalTunnelKey(dstNode, srcNode, tunType))
382 .setSourceDevice(srcNode).setDestinationDevice(dstNode)
383 .setTunnelInterfaceName(trunkInterfaceName)
384 .setTransportType(tunType).build();
387 private static String getUniqueIdString(String idKey) {
388 return UUID.nameUUIDFromBytes(idKey.getBytes(StandardCharsets.UTF_8)).toString().substring(0, 12)
392 public static List<DPNTEPsInfo> getDpnTepListFromDpnId(DPNTEPsInfoCache dpnTEPsInfoCache, List<Uint64> dpnIds) {
393 Collection<DPNTEPsInfo> meshedDpnList = dpnTEPsInfoCache.getAllPresent();
394 List<DPNTEPsInfo> cfgDpnList = new ArrayList<>();
395 for (Uint64 dpnId : dpnIds) {
396 for (DPNTEPsInfo teps : meshedDpnList) {
397 if (dpnId.equals(teps.getDPNID())) {
398 cfgDpnList.add(teps);
406 @SuppressWarnings("checkstyle:IllegalCatch")
407 public static void addTerminatingServiceTable(TypedReadWriteTransaction<Configuration> tx,
408 Uint64 dpnId, IMdsalApiManager mdsalManager) {
409 LOG.trace("Installing PUNT to Controller flow in DPN {} ", dpnId);
410 List<ActionInfo> listActionInfo = new ArrayList<>();
411 listActionInfo.add(new ActionPuntToController());
414 List<MatchInfo> mkMatches = new ArrayList<>();
416 mkMatches.add(new MatchTunnelId(Uint64.valueOf(ITMConstants.LLDP_SERVICE_ID)));
418 List<InstructionInfo> mkInstructions = new ArrayList<>();
419 mkInstructions.add(new InstructionApplyActions(listActionInfo));
421 FlowEntity terminatingServiceTableFlowEntity = MDSALUtil
422 .buildFlowEntity(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE,
423 getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE, ITMConstants.LLDP_SERVICE_ID),
424 5, ITM_LLDP_FLOW_ENTRY, 0, 0,
425 COOKIE_ITM_LLD, mkMatches, mkInstructions);
426 mdsalManager.addFlow(tx, terminatingServiceTableFlowEntity);
427 } catch (Exception e) {
428 LOG.error("Error while setting up Table 36 for {}", dpnId, e);
432 @SuppressWarnings("checkstyle:IllegalCatch")
433 public static void removeTerminatingServiceTable(TypedReadWriteTransaction<Configuration> tx,
434 Uint64 dpnId, IMdsalApiManager mdsalManager) {
435 LOG.trace("Removing PUNT to Controller flow in DPN {} ", dpnId);
438 mdsalManager.removeFlow(tx, dpnId,
439 getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE, ITMConstants.LLDP_SERVICE_ID),
440 NwConstants.INTERNAL_TUNNEL_TABLE);
441 } catch (Exception e) {
442 LOG.error("Error while setting up Table 36 for {}", dpnId, e);
446 private static String getFlowRef(long termSvcTable, int svcId) {
447 return String.valueOf(termSvcTable) + svcId;
450 public static <T> boolean isEmpty(Collection<T> collection) {
451 return collection == null || collection.isEmpty();
454 public static @NonNull HwVtep createHwVtepObject(String topoId, String nodeId, IpAddress ipAddress,
455 Class<? extends TunnelTypeBase> tunneltype,
456 TransportZone transportZone) {
457 HwVtep hwVtep = new HwVtep();
458 hwVtep.setHwIp(ipAddress);
459 hwVtep.setNodeId(nodeId);
460 hwVtep.setTopoId(topoId);
461 hwVtep.setTransportZone(transportZone.getZoneName());
462 hwVtep.setTunnelType(tunneltype);
466 public static String getHwParentIf(String topoId, String srcNodeid) {
467 return topoId + ":" + srcNodeid;
471 * Synchronous blocking write to data store.
474 * {@link SingleTransactionDataBroker#syncWrite(DataBroker, LogicalDatastoreType, InstanceIdentifier, DataObject)}
477 public static <T extends DataObject> void syncWrite(LogicalDatastoreType datastoreType,
478 InstanceIdentifier<T> path, T data, DataBroker broker) {
479 WriteTransaction tx = broker.newWriteOnlyTransaction();
480 tx.mergeParentStructurePut(datastoreType, path, data);
483 } catch (InterruptedException | ExecutionException e) {
484 LOG.error("ITMUtils:SyncWrite , Error writing to datastore (path, data) : ({}, {})", path, data);
485 throw new RuntimeException(e.getMessage(), e);
489 public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces
490 .rev140508.interfaces.state.Interface> buildStateInterfaceId(
491 String interfaceName) {
492 return InstanceIdentifier.builder(InterfacesState.class)
493 .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
494 .state.Interface.class,
495 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces
496 .rev140508.interfaces.state.InterfaceKey(
497 interfaceName)).build();
501 public static List<String> getInternalTunnelInterfaces(DataBroker dataBroker) {
502 Collection<String> internalInterfaces = ITM_CACHE.getAllInternalInterfaces();
503 List<String> tunnelList = new ArrayList<>();
504 if (internalInterfaces.isEmpty()) {
505 tunnelList = getAllInternalTunnlInterfacesFromDS(dataBroker);
507 LOG.debug("Internal Interfaces from Cache size: {}", internalInterfaces.size());
508 tunnelList.addAll(internalInterfaces);
510 LOG.trace("ItmUtils Internal TunnelList: {}", tunnelList);
514 public static Map<InternalTunnelKey, InternalTunnel> getInternalTunnelsFromCache(DataBroker dataBroker) {
515 Collection<InternalTunnel> internalInterfaces = ITM_CACHE.getAllInternalTunnel();
516 LOG.trace("getInternalTunnelsFromCache - List of InternalTunnels in the Cache: {} ", internalInterfaces);
517 Map<InternalTunnelKey, InternalTunnel> tunnelMap = new HashMap<>();
518 if (internalInterfaces.isEmpty()) {
519 LOG.trace("ItmUtils.getInternalTunnelsFromCache invoking getAllInternalTunnlInterfacesFromDS");
520 tunnelMap = getAllInternalTunnels(dataBroker);
522 LOG.debug("No. of Internal Tunnel Interfaces in cache: {} ", internalInterfaces.size());
523 for (InternalTunnel internalTunnel : internalInterfaces) {
524 tunnelMap.put(internalTunnel.key(), internalTunnel);
527 LOG.trace("List of Internal Tunnels: {}", tunnelMap);
531 @SuppressFBWarnings("RV_CHECK_FOR_POSITIVE_INDEXOF")
532 public static ExternalTunnelKey getExternalTunnelKey(String dst, String src,
533 Class<? extends TunnelTypeBase> tunType) {
534 final int srcIndex = src.indexOf("physicalswitch");
536 src = src.substring(0, srcIndex - 1);
538 final int dstIndex = dst.indexOf("physicalswitch");
540 dst = dst.substring(0, dstIndex - 1);
542 return new ExternalTunnelKey(dst, src, tunType);
545 public static List<TunnelEndPoints> getTEPsForDpn(Uint64 srcDpn, Collection<DPNTEPsInfo> dpnList) {
546 for (DPNTEPsInfo dpn : dpnList) {
547 if (Objects.equals(dpn.getDPNID(), srcDpn)) {
548 return new ArrayList<>(dpn.nonnullTunnelEndPoints());
554 public static Map<InternalTunnelKey, InternalTunnel> getAllInternalTunnels(DataBroker dataBroker) {
555 Map<InternalTunnelKey, InternalTunnel> result = null;
556 InstanceIdentifier<TunnelList> iid = InstanceIdentifier.builder(TunnelList.class).build();
557 Optional<TunnelList> tunnelList = read(LogicalDatastoreType.CONFIGURATION, iid, dataBroker);
559 if (tunnelList.isPresent()) {
560 result = tunnelList.get().getInternalTunnel();
562 if (result == null) {
568 public static InternalTunnel getInternalTunnel(String interfaceName, DataBroker broker) {
569 InternalTunnel internalTunnel = ITM_CACHE.getInternalTunnel(interfaceName);
570 LOG.trace("ItmUtils getInternalTunnel List of InternalTunnels in the Cache {} ", internalTunnel);
571 if (internalTunnel == null) {
572 internalTunnel = getInternalTunnelFromDS(interfaceName, broker);
574 return internalTunnel;
577 private static List<String> getAllInternalTunnlInterfacesFromDS(DataBroker broker) {
578 List<String> tunnelList = new ArrayList<>();
579 Map<InternalTunnelKey, InternalTunnel> internalTunnels = getAllInternalTunnels(broker);
580 if (internalTunnels != null) {
581 for (InternalTunnel tunnel : internalTunnels.values()) {
582 List<String> tunnelInterfaceNames = tunnel.getTunnelInterfaceNames();
583 if (tunnelInterfaceNames != null) {
584 for (String tunnelInterfaceName : tunnelInterfaceNames) {
585 tunnelList.add(tunnelInterfaceName);
590 LOG.debug("Internal Tunnel Interfaces list: {} ", tunnelList);
594 private static ExternalTunnel getExternalTunnelFromDS(String interfaceName, DataBroker broker) {
595 Map<ExternalTunnelKey, ExternalTunnel> externalTunnels = getAllExternalTunnels(broker);
596 if (externalTunnels != null) {
597 for (ExternalTunnel tunnel : externalTunnels.values()) {
598 String tunnelInterfaceName = tunnel.getTunnelInterfaceName();
599 if (tunnelInterfaceName != null && tunnelInterfaceName.equalsIgnoreCase(interfaceName)) {
600 LOG.trace("getExternalTunnelFromDS tunnelInterfaceName: {} ", tunnelInterfaceName);
608 public static ExternalTunnel getExternalTunnel(String interfaceName, DataBroker broker) {
609 ExternalTunnel externalTunnel = ITM_CACHE.getExternalTunnel(interfaceName);
610 if (externalTunnel == null) {
611 externalTunnel = getExternalTunnelFromDS(interfaceName, broker);
613 LOG.trace("getExternalTunnel externalTunnel: {} ", externalTunnel);
614 return externalTunnel;
617 private static Map<ExternalTunnelKey, ExternalTunnel> getAllExternalTunnels(DataBroker dataBroker) {
618 Map<ExternalTunnelKey, ExternalTunnel> result = null;
619 InstanceIdentifier<ExternalTunnelList> iid = InstanceIdentifier.builder(ExternalTunnelList.class).build();
620 Optional<ExternalTunnelList> tunnelList = read(LogicalDatastoreType.CONFIGURATION, iid, dataBroker);
621 if (tunnelList.isPresent()) {
622 result = tunnelList.get().getExternalTunnel();
624 if (result == null) {
630 public static String convertTunnelTypetoString(Class<? extends TunnelTypeBase> tunType) {
631 String tunnelType = ITMConstants.TUNNEL_TYPE_VXLAN;
632 if (tunType.equals(TunnelTypeVxlan.class)) {
633 tunnelType = ITMConstants.TUNNEL_TYPE_VXLAN;
634 } else if (tunType.equals(TunnelTypeGre.class)) {
635 tunnelType = ITMConstants.TUNNEL_TYPE_GRE;
636 } else if (tunType.equals(TunnelTypeMplsOverGre.class)) {
637 tunnelType = ITMConstants.TUNNEL_TYPE_MPLSoGRE;
638 } else if (tunType.equals(TunnelTypeLogicalGroup.class)) {
639 tunnelType = ITMConstants.TUNNEL_TYPE_LOGICAL_GROUP_VXLAN;
645 public static boolean isItmIfType(Class<? extends InterfaceType> ifType) {
646 return ifType != null && ifType.isAssignableFrom(Tunnel.class);
649 public static StateTunnelListKey getTunnelStateKey(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
650 .interfaces.rev140508.interfaces.state.Interface iface) {
651 StateTunnelListKey key = null;
652 if (isItmIfType(iface.getType())) {
653 key = new StateTunnelListKey(iface.getName());
658 public static Interface getInterface(
659 String name, IInterfaceManager ifaceManager) {
660 Interface result = ITM_CACHE.getInterface(name);
661 if (result == null) {
662 result = ifaceManager.getInterfaceInfoFromConfigDataStore(name);
663 if (result != null) {
664 ITM_CACHE.addInterface(result);
670 public static boolean falseIfNull(Boolean value) {
671 return value == null ? false : value;
674 public static List<TzMembership> getIntersection(Map<TzMembershipKey, TzMembership> list1,
675 Map<TzMembershipKey, TzMembership> list2) {
676 List<TzMembership> list = new ArrayList<>();
677 for (TzMembership iter : list1.values()) {
678 if (list2.values().contains(iter)) {
682 LOG.debug(" getIntersection - L1 {}, L2 - {}, Intersection - {}", list1, list2, list);
686 public static void addTransportZoneMembership(List<TzMembership> zones, String zoneName) {
687 zones.add(new TzMembershipBuilder().setZoneName(zoneName).build());
690 public static List<TzMembership> createTransportZoneMembership(String zoneName) {
691 List<TzMembership> zones = new ArrayList<>();
692 zones.add(new TzMembershipBuilder().setZoneName(zoneName).build());
697 * Gets the transport zone in TepsNotHosted list in the Operational Datastore, based on transport zone name.
699 * @param unknownTz transport zone name
700 * @param dataBroker data broker handle to perform read operations on Oper datastore
701 * @return the TepsInNotHostedTransportZone object in the TepsNotHosted list in Oper DS
703 public static TepsInNotHostedTransportZone getUnknownTransportZoneFromITMOperDS(
704 String unknownTz, DataBroker dataBroker) {
705 InstanceIdentifier<TepsInNotHostedTransportZone> unknownTzPath =
706 InstanceIdentifier.builder(NotHostedTransportZones.class)
707 .child(TepsInNotHostedTransportZone.class,
708 new TepsInNotHostedTransportZoneKey(unknownTz)).build();
709 Optional<TepsInNotHostedTransportZone> unknownTzOptional =
710 ItmUtils.read(LogicalDatastoreType.OPERATIONAL, unknownTzPath, dataBroker);
711 if (unknownTzOptional.isPresent()) {
712 return unknownTzOptional.get();
718 * Gets the bridge datapath ID from Network topology Node's OvsdbBridgeAugmentation, in the Operational DS.
720 * @param node Network Topology Node
721 * @param bridge bridge name
722 * @param dataBroker data broker handle to perform operations on datastore
723 * @return the datapath ID of bridge in string form
725 public static String getBridgeDpid(Node node, String bridge, DataBroker dataBroker) {
726 OvsdbBridgeAugmentation ovsdbBridgeAugmentation = null;
727 Node bridgeNode = null;
728 String datapathId = null;
730 NodeId ovsdbNodeId = node.key().getNodeId();
732 NodeId brNodeId = new NodeId(ovsdbNodeId.getValue()
733 + "/" + ITMConstants.BRIDGE_URI_PREFIX + "/" + bridge);
735 InstanceIdentifier<Node> bridgeIid =
737 .create(NetworkTopology.class)
738 .child(Topology.class, new TopologyKey(IfmConstants.OVSDB_TOPOLOGY_ID))
739 .child(Node.class, new NodeKey(brNodeId));
741 Optional<Node> opBridgeNode = ItmUtils.read(LogicalDatastoreType.OPERATIONAL, bridgeIid, dataBroker);
743 if (opBridgeNode.isPresent()) {
744 bridgeNode = opBridgeNode.get();
746 if (bridgeNode != null) {
747 ovsdbBridgeAugmentation = bridgeNode.augmentation(OvsdbBridgeAugmentation.class);
750 if (ovsdbBridgeAugmentation != null && ovsdbBridgeAugmentation.getDatapathId() != null) {
751 datapathId = ovsdbBridgeAugmentation.getDatapathId().getValue();
757 * Gets the Network topology Node from Operational Datastore
758 * based on Bridge Augmentation.
760 * @param bridgeAugmentation bridge augmentation of OVSDB node
761 * @param dataBroker data broker handle to perform operations on datastore
762 * @return the Network Topology Node i.e. OVSDB node which is managing the specified bridge
764 public static Node getOvsdbNode(OvsdbBridgeAugmentation bridgeAugmentation,
765 DataBroker dataBroker) {
766 Node ovsdbNode = null;
767 Optional<Node> opOvsdbNode = Optional.empty();
768 if (bridgeAugmentation != null) {
769 InstanceIdentifier<Node> ovsdbNodeIid =
770 (InstanceIdentifier<Node>) bridgeAugmentation.getManagedBy().getValue();
771 opOvsdbNode = ItmUtils.read(LogicalDatastoreType.OPERATIONAL, ovsdbNodeIid, dataBroker);
773 if (opOvsdbNode.isPresent()) {
774 ovsdbNode = opOvsdbNode.get();
780 * Gets the bridge datapath ID in string form from
781 * Network topology Node's OvsdbBridgeAugmentation in the Operational DS.
783 * @param augmentedNode Ovsdb Augmented Network Topology Node
784 * @return the datapath ID of bridge in string form
786 public static String getStrDatapathId(OvsdbBridgeAugmentation augmentedNode) {
787 String datapathId = null;
788 if (augmentedNode != null && augmentedNode.getDatapathId() != null) {
789 datapathId = augmentedNode.getDatapathId().getValue();
795 * Returns the dummy subnet (255.255.255.255/32) as IpPrefix object.
797 * @return the dummy subnet (255.255.255.255/32) in IpPrefix object
799 public static IpPrefix getDummySubnet() {
800 return DUMMY_IP_PREFIX;
804 * Deletes the transport zone from Configuration datastore.
806 * @param tzName transport zone name
807 * @param dataBroker data broker handle to perform operations on datastore
809 public static void deleteTransportZoneFromConfigDS(String tzName, DataBroker dataBroker) {
810 // check whether transport-zone exists in config DS.
811 TransportZone transportZoneFromConfigDS = ItmUtils.getTransportZoneFromConfigDS(tzName, dataBroker);
812 if (transportZoneFromConfigDS != null) {
813 // it exists, delete default-TZ now
814 InstanceIdentifier<TransportZone> path = InstanceIdentifier.builder(TransportZones.class)
815 .child(TransportZone.class, new TransportZoneKey(tzName)).build();
816 LOG.debug("Removing {} transport-zone from config DS.", tzName);
818 SingleTransactionDataBroker.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, path);
819 } catch (TransactionCommitFailedException e) {
820 LOG.error("deleteTransportZoneFromConfigDS failed. {} could not be deleted.", tzName, e);
826 * Validates the tunnelType argument and returnsTunnelTypeBase class object
827 * corresponding to tunnelType obtained in String format.
829 * @param tunnelType type of tunnel in string form
830 * @return tunnel-type in TunnelTypeBase object
832 public static Class<? extends TunnelTypeBase> getTunnelType(String tunnelType) {
833 // validate tunnelType string, in case it is NULL or empty, then
834 // take VXLAN tunnel type by default
835 if (tunnelType == null || tunnelType.isEmpty()) {
836 return TUNNEL_TYPE_MAP.get(ITMConstants.TUNNEL_TYPE_VXLAN);
837 } else if (!tunnelType.equals(ITMConstants.TUNNEL_TYPE_VXLAN)
838 && !tunnelType.equals(ITMConstants.TUNNEL_TYPE_GRE)) {
839 // if tunnel type is some incorrect value, then
840 // take VXLAN tunnel type by default
841 return TUNNEL_TYPE_MAP.get(ITMConstants.TUNNEL_TYPE_VXLAN);
844 // return TunnelTypeBase object corresponding to tunnel-type
845 return TUNNEL_TYPE_MAP.get(tunnelType);
848 public static List<TzMembership> removeTransportZoneMembership(TunnelEndPoints endPts,
850 TzMembership> zones) {
851 LOG.trace(" RemoveTransportZoneMembership TEPs {}, Membership to be removed {} ", endPts, zones);
852 List<TzMembership> existingTzList = new ArrayList<>(endPts.nonnullTzMembership().values());
853 for (TzMembership membership : zones.values()) {
854 existingTzList.remove(membership);
856 LOG.debug("Modified Membership Map {}", existingTzList);
857 return existingTzList;
861 public static Map<TzMembershipKey, TzMembership> getOriginalTzMembership(TunnelEndPoints srcTep, Uint64 dpnId,
862 Collection<DPNTEPsInfo> meshedDpnList) {
863 LOG.trace("Original Membership for source DPN {}, source TEP {}", dpnId, srcTep);
864 for (DPNTEPsInfo dstDpn : meshedDpnList) {
865 if (dpnId.equals(dstDpn.getDPNID())) {
866 for (TunnelEndPoints tep : dstDpn.nonnullTunnelEndPoints()) {
867 if (Objects.equals(tep.getIpAddress(), srcTep.getIpAddress())) {
868 @NonNull Map<TzMembershipKey, TzMembership> tzMemberships = tep.nonnullTzMembership();
869 LOG.debug("Original Membership size {}", tzMemberships.size());
870 return tzMemberships;
878 public static StateTunnelList buildStateTunnelList(StateTunnelListKey tlKey, String name, boolean state,
879 TunnelOperStatus tunOpStatus, IInterfaceManager ifaceManager,
881 StateTunnelListBuilder stlBuilder = new StateTunnelListBuilder();
882 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface =
883 ItmUtils.getInterface(name, ifaceManager);
884 IfTunnel ifTunnel = iface.augmentation(IfTunnel.class);
885 ParentRefs parentRefs = iface.augmentation(ParentRefs.class);
886 if (ifTunnel == null || parentRefs == null) {
889 DstInfoBuilder dstInfoBuilder = new DstInfoBuilder();
890 SrcInfoBuilder srcInfoBuilder = new SrcInfoBuilder();
891 dstInfoBuilder.setTepIp(ifTunnel.getTunnelDestination());
892 srcInfoBuilder.setTepIp(ifTunnel.getTunnelSource());
893 // TODO: Add/Improve logic for device type
894 InternalTunnel internalTunnel = ItmUtils.ITM_CACHE.getInternalTunnel(name);
895 ExternalTunnel externalTunnel = ItmUtils.ITM_CACHE.getExternalTunnel(name);
896 if (internalTunnel == null && externalTunnel == null) {
897 // both not present in cache. let us update and try again.
898 internalTunnel = getInternalTunnel(name, broker);
899 externalTunnel = getExternalTunnel(name, broker);
901 if (internalTunnel != null) {
902 srcInfoBuilder.setTepDeviceId(internalTunnel.getSourceDPN().toString())
903 .setTepDeviceType(TepTypeInternal.class);
904 dstInfoBuilder.setTepDeviceId(internalTunnel.getDestinationDPN().toString())
905 .setTepDeviceType(TepTypeInternal.class);
906 stlBuilder.setTransportType(internalTunnel.getTransportType());
907 } else if (externalTunnel != null) {
908 ExternalTunnel tunnel = ItmUtils.ITM_CACHE.getExternalTunnel(name);
909 srcInfoBuilder.setTepDeviceId(tunnel.getSourceDevice())
910 .setTepDeviceType(getDeviceType(tunnel.getSourceDevice()));
911 dstInfoBuilder.setTepDeviceId(tunnel.getDestinationDevice())
912 .setTepDeviceType(getDeviceType(tunnel.getDestinationDevice()))
913 .setTepIp(ifTunnel.getTunnelDestination());
914 stlBuilder.setTransportType(tunnel.getTransportType());
916 stlBuilder.withKey(tlKey).setTunnelInterfaceName(name).setOperState(tunOpStatus).setTunnelState(state)
917 .setDstInfo(dstInfoBuilder.build()).setSrcInfo(srcInfoBuilder.build());
918 return stlBuilder.build();
921 private static Class<? extends TepTypeBase> getDeviceType(String device) {
922 if (device.startsWith("hwvtep")) {
923 return TepTypeHwvtep.class;
924 } else if (InetAddresses.isInetAddress(device)) {
925 // In case of external tunnel, destination-device will be of IP address type.
926 return TepTypeExternal.class;
928 return TepTypeInternal.class;
932 public static InstanceIdentifier<StateTunnelList> buildStateTunnelListId(StateTunnelListKey tlKey) {
933 return InstanceIdentifier.builder(TunnelsState.class).child(StateTunnelList.class, tlKey).build();
936 public static InstanceIdentifier<OfTep> buildStateOfTepListId(OfTepKey ofTepKey) {
937 return InstanceIdentifier.builder(OfTepsState.class)
938 .child(OfTep.class, ofTepKey).build();
942 public static Optional<InternalTunnel> getInternalTunnelFromDS(Uint64 srcDpn, Uint64 destDpn,
943 Class<? extends TunnelTypeBase> type,
944 DataBroker dataBroker) {
945 InstanceIdentifier<InternalTunnel> pathLogicTunnel = InstanceIdentifier.create(TunnelList.class)
946 .child(InternalTunnel.class,
947 new InternalTunnelKey(destDpn, srcDpn, type));
948 //TODO: need to be replaced by cached copy
949 return ItmUtils.read(LogicalDatastoreType.CONFIGURATION, pathLogicTunnel, dataBroker);
952 private static InternalTunnel getInternalTunnelFromDS(String interfaceName, DataBroker broker) {
953 Map<InternalTunnelKey, InternalTunnel> internalTunnels = getAllInternalTunnels(broker);
954 if (internalTunnels != null) {
955 for (InternalTunnel tunnel : internalTunnels.values()) {
956 List<String> tunnelInterfaceNames = tunnel.getTunnelInterfaceNames();
957 if (tunnelInterfaceNames != null) {
958 for (String tunnelInterfaceName : tunnelInterfaceNames) {
959 if (tunnelInterfaceName.equalsIgnoreCase(interfaceName)) {
960 LOG.trace("ItmUtils getInternalTunnelFromDS {} ", tunnelInterfaceName);
970 public static boolean isTunnelAggregationUsed(Class<? extends TunnelTypeBase> tunType) {
971 return ItmTunnelAggregationHelper.isTunnelAggregationEnabled()
972 && (tunType.isAssignableFrom(TunnelTypeVxlan.class)
973 || tunType.isAssignableFrom(TunnelTypeLogicalGroup.class));
976 public static List<TunnelOptions> buildTunnelOptions(TunnelEndPoints tep, ItmConfig itmConfig) {
977 List<TunnelOptions> tunOptions = new ArrayList<>();
979 String tos = tep.getOptionTunnelTos();
981 tos = itmConfig.getDefaultTunnelTos();
983 /* populate tos option only if its not default value of 0 */
984 if (tos != null && !tos.equals("0")) {
985 TunnelOptionsBuilder optionsBuilder = new TunnelOptionsBuilder();
986 optionsBuilder.withKey(new TunnelOptionsKey("tos"));
987 optionsBuilder.setTunnelOption("tos");
988 optionsBuilder.setValue(tos);
989 tunOptions.add(optionsBuilder.build());
992 if (tep.getTunnelType() == TunnelTypeVxlan.class && itmConfig.isGpeExtensionEnabled()) {
993 TunnelOptionsBuilder optionsBuilder = new TunnelOptionsBuilder();
994 optionsBuilder.withKey(new TunnelOptionsKey("exts"));
995 optionsBuilder.setTunnelOption("exts");
996 optionsBuilder.setValue("gpe");
997 tunOptions.add(optionsBuilder.build());
999 return tunOptions.isEmpty() ? null : tunOptions;
1002 public static ExternalTunnel getExternalTunnelbyExternalTunnelKey(ExternalTunnelKey externalTunnelKey,
1003 InstanceIdentifier<ExternalTunnel> path,
1004 DataBroker dataBroker) {
1005 ExternalTunnel exTunnel = ITM_CACHE.getExternalTunnelKeyToExternalTunnels().get(externalTunnelKey);
1006 if (exTunnel == null) {
1007 Optional<ExternalTunnel> ext = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
1008 if (ext.isPresent()) {
1009 exTunnel = ext.get();
1015 public static List<DPNTEPsInfo> getDpnTEPsInfos(DataBroker dataBroker) {
1016 InstanceIdentifier<DpnEndpoints> iid = InstanceIdentifier.builder(DpnEndpoints.class).build();
1017 Optional<DpnEndpoints> dpnEndpoints = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, iid, dataBroker);
1018 if (dpnEndpoints.isPresent()) {
1019 return new ArrayList<>(dpnEndpoints.get().getDPNTEPsInfo().values());
1021 return new ArrayList<>();
1025 public static InstanceIdentifier<TransportZone> getTZInstanceIdentifier(String tzName) {
1026 return InstanceIdentifier.builder(TransportZones.class).child(TransportZone.class,
1027 new TransportZoneKey(tzName)).build();
1031 * Returns the transport zone from Configuration datastore.
1033 * @param tzName transport zone name
1034 * @param dataBroker data broker handle to perform operations on datastore
1035 * @return the TransportZone object in Config DS
1037 // FIXME: Better is to implement cache to avoid datastore read.
1038 public static TransportZone getTransportZoneFromConfigDS(String tzName, DataBroker dataBroker) {
1039 InstanceIdentifier<TransportZone> tzonePath = getTZInstanceIdentifier(tzName);
1040 Optional<TransportZone> transportZoneOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, tzonePath,
1042 if (transportZoneOptional.isPresent()) {
1043 return transportZoneOptional.get();
1049 * Returns the transport zone of vtep from Configuration datastore.
1051 * @param dpid datapath id of vtep
1052 * @param dataBroker data broker handle to perform operations on datastore
1053 * @return the TransportZone object in Config DS
1055 public static TransportZone getTransportZoneOfVtep(Uint64 dpid, DataBroker dataBroker) {
1056 InstanceIdentifier<TransportZones> path = InstanceIdentifier.builder(TransportZones.class).build();
1057 Optional<TransportZones> transportZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
1059 if (transportZonesOptional.isPresent()) {
1060 TransportZones tzones = transportZonesOptional.get();
1061 for (TransportZone tzone : tzones.getTransportZone()) {
1062 List<Vteps> vtepList = new ArrayList<>(tzone.nonnullVteps().values());
1063 if (vtepList != null && !vtepList.isEmpty()) {
1064 for (Vteps vtep : vtepList) {
1065 if (vtep.getDpnId().equals(dpid)) {
1075 public static Class<? extends TunnelTypeBase> convertStringToTunnelType(String tunnelType) {
1076 Class<? extends TunnelTypeBase> tunType = TunnelTypeVxlan.class;
1077 if (STRING_CLASS_IMMUTABLE_BI_MAP.containsKey(tunnelType)) {
1078 tunType = STRING_CLASS_IMMUTABLE_BI_MAP.get(tunnelType);
1083 public static List<Uint64> getDpIdFromTransportzone(DataBroker dataBroker, String tzone) {
1084 List<Uint64> listOfDpId = new ArrayList<>();
1085 InstanceIdentifier<TransportZone> path = InstanceIdentifier.builder(TransportZones.class)
1086 .child(TransportZone.class, new TransportZoneKey(tzone)).build();
1087 Optional<TransportZone> transportZoneOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
1089 if (transportZoneOptional.isPresent()) {
1090 TransportZone transportZone = transportZoneOptional.get();
1091 if (transportZone.getVteps() != null && !transportZone.getVteps().isEmpty()) {
1092 @Nullable Map<VtepsKey, Vteps> vtepsList = transportZone.getVteps();
1093 if (vtepsList != null && !vtepsList.isEmpty()) {
1094 for (Vteps vtep : vtepsList.values()) {
1095 listOfDpId.add(vtep.getDpnId());
1103 public static String generateOfPortName(Uint64 dpId, IpAddress tepIp, String tunnelType) {
1104 String trunkInterfaceName = String.format("%s:%s:%s", dpId.toString(), tepIp.stringValue(),
1106 String uuidStr = UUID.nameUUIDFromBytes(trunkInterfaceName.getBytes(StandardCharsets.UTF_8)).toString()
1107 .substring(0, 12).replace("-", "");
1108 return String.format("%s%s", "of", uuidStr);
1111 public static OfDpnTep createDpnOFTepInfo(Uint64 dpnID, IpAddress ipAddress,
1112 String ofPortName, Class<? extends TunnelTypeBase> tunnelType) {
1113 OfDpnTepBuilder tepBuilder = new OfDpnTepBuilder();
1114 tepBuilder.withKey(new OfDpnTepKey(dpnID));
1115 tepBuilder.setOfPortName(ofPortName);
1116 tepBuilder.setSourceDpnId(dpnID);
1117 tepBuilder.setTepIp(ipAddress);
1118 tepBuilder.setTunnelType(tunnelType);
1119 return tepBuilder.build();