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 com.google.common.base.Optional;
11 import com.google.common.base.Preconditions;
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 com.google.common.util.concurrent.Futures;
18 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
19 import java.math.BigInteger;
20 import java.net.InetAddress;
21 import java.nio.charset.StandardCharsets;
22 import java.util.ArrayList;
23 import java.util.Collection;
24 import java.util.Collections;
25 import java.util.List;
26 import java.util.UUID;
27 import java.util.concurrent.ExecutionException;
28 import javax.annotation.Nonnull;
29 import org.apache.commons.lang3.StringUtils;
30 import org.apache.commons.net.util.SubnetUtils;
31 import org.apache.commons.net.util.SubnetUtils.SubnetInfo;
32 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
33 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
34 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
35 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
36 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
37 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
38 import org.opendaylight.genius.infra.Datastore.Configuration;
39 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
40 import org.opendaylight.genius.infra.TypedReadWriteTransaction;
41 import org.opendaylight.genius.interfacemanager.globals.IfmConstants;
42 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
43 import org.opendaylight.genius.itm.api.IITMProvider;
44 import org.opendaylight.genius.itm.cache.DPNTEPsInfoCache;
45 import org.opendaylight.genius.itm.confighelpers.HwVtep;
46 import org.opendaylight.genius.itm.confighelpers.ItmTunnelAggregationHelper;
47 import org.opendaylight.genius.itm.globals.ITMConstants;
48 import org.opendaylight.genius.mdsalutil.ActionInfo;
49 import org.opendaylight.genius.mdsalutil.FlowEntity;
50 import org.opendaylight.genius.mdsalutil.InstructionInfo;
51 import org.opendaylight.genius.mdsalutil.MDSALUtil;
52 import org.opendaylight.genius.mdsalutil.MatchInfo;
53 import org.opendaylight.genius.mdsalutil.NwConstants;
54 import org.opendaylight.genius.mdsalutil.actions.ActionPuntToController;
55 import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
56 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
57 import org.opendaylight.genius.mdsalutil.matches.MatchTunnelId;
58 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel;
59 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
60 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder;
61 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
62 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefixBuilder;
63 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType;
64 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
65 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
66 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
67 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
68 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlanBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnel;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnelBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefs;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefsBuilder;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelMonitoringTypeBase;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeGre;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeLogicalGroup;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeMplsOverGre;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.interfaces._interface.NodeIdentifier;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.interfaces._interface.NodeIdentifierBuilder;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.interfaces._interface.NodeIdentifierKey;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.tunnel.optional.params.TunnelOptions;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.tunnel.optional.params.TunnelOptionsBuilder;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.tunnel.optional.params.TunnelOptionsKey;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.ItmConfig;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.VtepConfigSchemas;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.VtepIpPools;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.VtepConfigSchema;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.VtepConfigSchemaBuilder;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.VtepConfigSchemaKey;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.vtep.config.schema.DpnIds;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.vtep.config.schema.DpnIdsBuilder;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.vtep.config.schema.DpnIdsKey;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.ip.pools.VtepIpPool;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.ip.pools.VtepIpPoolKey;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpointsBuilder;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.ExternalTunnelList;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeBase;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeExternal;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeHwvtep;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeInternal;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelList;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelOperStatus;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelsState;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoBuilder;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoKey;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPointsBuilder;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPointsKey;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.tunnel.end.points.TzMembership;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.tunnel.end.points.TzMembershipBuilder;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnel;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnelBuilder;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnelKey;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnel;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnelBuilder;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnelKey;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelList;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelListBuilder;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelListKey;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.state.tunnel.list.DstInfoBuilder;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.state.tunnel.list.SrcInfoBuilder;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.DcGatewayIpList;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.NotHostedTransportZones;
129 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZones;
130 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.dc.gateway.ip.list.DcGatewayIp;
131 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.not.hosted.transport.zones.TepsInNotHostedTransportZone;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.not.hosted.transport.zones.TepsInNotHostedTransportZoneKey;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZone;
134 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZoneKey;
135 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.Subnets;
136 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.Vteps;
137 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
138 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
139 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
140 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
141 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
142 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
143 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
144 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
145 import org.opendaylight.yangtools.yang.binding.DataObject;
146 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
147 import org.slf4j.Logger;
148 import org.slf4j.LoggerFactory;
150 public final class ItmUtils {
152 private static final Logger LOG = LoggerFactory.getLogger(ItmUtils.class);
154 private static final String TUNNEL = "tun";
155 private static final IpPrefix DUMMY_IP_PREFIX = IpPrefixBuilder.getDefaultInstance(ITMConstants.DUMMY_PREFIX);
156 private static final long DEFAULT_MONITORING_INTERVAL = 100L;
157 public static final ItmCache ITM_CACHE = new ItmCache();
159 public static final ImmutableMap<String, Class<? extends TunnelTypeBase>>
161 new ImmutableMap.Builder<String, Class<? extends TunnelTypeBase>>()
162 .put(ITMConstants.TUNNEL_TYPE_GRE, TunnelTypeGre.class)
163 .put(ITMConstants.TUNNEL_TYPE_MPLSoGRE, TunnelTypeMplsOverGre.class)
164 .put(ITMConstants.TUNNEL_TYPE_VXLAN, TunnelTypeVxlan.class)
167 private static final BiMap<String,Class<? extends TunnelTypeBase>> STRING_CLASS_IMMUTABLE_BI_MAP =
168 ImmutableBiMap.copyOf(TUNNEL_TYPE_MAP);
173 public static final FutureCallback<Void> DEFAULT_CALLBACK = new FutureCallback<Void>() {
175 public void onSuccess(Void result) {
176 LOG.debug("Success in Datastore write operation");
180 public void onFailure(@Nonnull Throwable error) {
181 LOG.error("Error in Datastore write operation", error);
186 * Synchronous blocking read from data store.
189 * {@link SingleTransactionDataBroker#syncReadOptional(DataBroker, LogicalDatastoreType, InstanceIdentifier)}
193 @SuppressWarnings("checkstyle:IllegalCatch")
194 public static <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType,
195 InstanceIdentifier<T> path, DataBroker broker) {
196 try (ReadOnlyTransaction tx = broker.newReadOnlyTransaction()) {
197 return tx.read(datastoreType, path).get();
198 } catch (Exception e) {
199 throw new RuntimeException(e);
205 * Asynchronous non-blocking write to data store.
207 * @deprecated Use {@link ManagedNewTransactionRunner} instead of this.
210 public static <T extends DataObject> void asyncWrite(LogicalDatastoreType datastoreType,
211 InstanceIdentifier<T> path, T data, DataBroker broker,
212 FutureCallback<Void> callback) {
213 WriteTransaction tx = broker.newWriteOnlyTransaction();
214 tx.put(datastoreType, path, data, true);
215 Futures.addCallback(tx.submit(), callback);
219 * Asynchronous non-blocking update to data store.
221 * @deprecated Use {@link ManagedNewTransactionRunner} instead of this.
224 public static <T extends DataObject> void asyncUpdate(LogicalDatastoreType datastoreType,
225 InstanceIdentifier<T> path, T data, DataBroker broker,
226 FutureCallback<Void> callback) {
227 WriteTransaction tx = broker.newWriteOnlyTransaction();
228 tx.merge(datastoreType, path, data, true);
229 Futures.addCallback(tx.submit(), callback);
233 * Asynchronous non-blocking single delete to data store.
235 * @deprecated Use {@link ManagedNewTransactionRunner} instead of this.
238 public static <T extends DataObject> void asyncDelete(LogicalDatastoreType datastoreType,
239 InstanceIdentifier<T> path, DataBroker broker,
240 FutureCallback<Void> callback) {
241 WriteTransaction tx = broker.newWriteOnlyTransaction();
242 tx.delete(datastoreType, path);
243 Futures.addCallback(tx.submit(), callback);
247 * Asynchronous non-blocking bulk delete to data store.
249 * @deprecated Use {@link ManagedNewTransactionRunner} instead of this.
252 public static <T extends DataObject> void asyncBulkRemove(final DataBroker broker,
253 final LogicalDatastoreType datastoreType,
254 List<InstanceIdentifier<T>> pathList,
255 FutureCallback<Void> callback) {
256 if (!pathList.isEmpty()) {
257 WriteTransaction tx = broker.newWriteOnlyTransaction();
258 for (InstanceIdentifier<T> path : pathList) {
259 tx.delete(datastoreType, path);
261 Futures.addCallback(tx.submit(), callback);
265 public static String getInterfaceName(final BigInteger datapathid, final String portName, final Integer vlanId) {
266 return String.format("%s:%s:%s", datapathid, portName, vlanId);
269 public static BigInteger getDpnIdFromInterfaceName(String interfaceName) {
270 String[] dpnStr = interfaceName.split(":");
271 return new BigInteger(dpnStr[0]);
274 public static String getTrunkInterfaceName(String parentInterfaceName,
275 String localHostName, String remoteHostName, String tunnelType) {
276 String tunnelTypeStr;
277 if (tunnelType.contains("TunnelTypeGre")) {
278 tunnelTypeStr = ITMConstants.TUNNEL_TYPE_GRE;
279 } else if (tunnelType.contains("TunnelTypeLogicalGroup")) {
280 tunnelTypeStr = ITMConstants.TUNNEL_TYPE_LOGICAL_GROUP_VXLAN;
282 tunnelTypeStr = ITMConstants.TUNNEL_TYPE_VXLAN;
284 String trunkInterfaceName = String.format("%s:%s:%s:%s", parentInterfaceName, localHostName,
285 remoteHostName, tunnelTypeStr);
286 LOG.trace("trunk interface name is {}", trunkInterfaceName);
287 trunkInterfaceName = String.format("%s%s", TUNNEL, getUniqueIdString(trunkInterfaceName));
288 return trunkInterfaceName;
291 public static void releaseIdForTrunkInterfaceName(String parentInterfaceName,
292 String localHostName, String remoteHostName, String tunnelType) {
293 String tunnelTypeStr;
294 if (tunnelType.contains("TunnelTypeGre")) {
295 tunnelTypeStr = ITMConstants.TUNNEL_TYPE_GRE;
297 tunnelTypeStr = ITMConstants.TUNNEL_TYPE_VXLAN;
299 String trunkInterfaceName = String.format("%s:%s:%s:%s", parentInterfaceName, localHostName,
300 remoteHostName, tunnelTypeStr);
301 LOG.trace("Releasing Id for trunkInterface - {}", trunkInterfaceName);
304 public static String getLogicalTunnelGroupName(BigInteger srcDpnId, BigInteger destDpnId) {
305 String tunnelTypeStr = ITMConstants.TUNNEL_TYPE_LOGICAL_GROUP_VXLAN;
306 String groupName = String.format("%s:%s:%s", srcDpnId.toString(), destDpnId.toString(), tunnelTypeStr);
307 LOG.trace("logical tunnel group name is {}", groupName);
308 groupName = String.format("%s%s", TUNNEL, getUniqueIdString(groupName));
312 public static InetAddress getInetAddressFromIpAddress(IpAddress ip) {
313 return InetAddresses.forString(String.valueOf(ip.getValue()));
316 public static InstanceIdentifier<DPNTEPsInfo> getDpnTepInstance(BigInteger dpIdKey) {
317 return InstanceIdentifier.builder(DpnEndpoints.class).child(DPNTEPsInfo.class, new DPNTEPsInfoKey(dpIdKey))
321 public static DPNTEPsInfo createDPNTepInfo(BigInteger dpId, List<TunnelEndPoints> endpoints) {
322 return new DPNTEPsInfoBuilder().withKey(new DPNTEPsInfoKey(dpId)).setTunnelEndPoints(endpoints).build();
325 public static TunnelEndPoints createTunnelEndPoints(BigInteger dpnId, IpAddress ipAddress, String portName,
326 boolean isOfTunnel, int vlanId, IpPrefix prefix,
327 IpAddress gwAddress, List<TzMembership> zones,
328 Class<? extends TunnelTypeBase> tunnelType,
330 // when Interface Mgr provides support to take in Dpn Id
331 return new TunnelEndPointsBuilder().withKey(new TunnelEndPointsKey(ipAddress, portName,tunnelType, vlanId))
332 .setSubnetMask(prefix).setGwIpAddress(gwAddress).setTzMembership(zones)
333 .setOptionOfTunnel(isOfTunnel).setInterfaceName(ItmUtils.getInterfaceName(dpnId, portName, vlanId))
334 .setTunnelType(tunnelType)
335 .setOptionTunnelTos(tos)
339 public static DpnEndpoints createDpnEndpoints(List<DPNTEPsInfo> dpnTepInfo) {
340 return new DpnEndpointsBuilder().setDPNTEPsInfo(dpnTepInfo).build();
343 public static InstanceIdentifier<Interface> buildId(String interfaceName) {
344 return InstanceIdentifier.builder(Interfaces.class).child(Interface.class, new InterfaceKey(interfaceName))
348 public static InstanceIdentifier<IfTunnel> buildTunnelId(String ifName) {
349 return InstanceIdentifier.builder(Interfaces.class)
350 .child(Interface.class, new InterfaceKey(ifName)).augmentation(IfTunnel.class).build();
353 public static Interface buildLogicalTunnelInterface(BigInteger dpn, String ifName, String desc, boolean enabled) {
354 InterfaceBuilder builder = new InterfaceBuilder().withKey(new InterfaceKey(ifName)).setName(ifName)
355 .setDescription(desc).setEnabled(enabled).setType(Tunnel.class);
356 ParentRefs parentRefs = new ParentRefsBuilder().setDatapathNodeIdentifier(dpn).build();
357 builder.addAugmentation(ParentRefs.class, parentRefs);
359 IfTunnel tunnel = new IfTunnelBuilder()
360 .setTunnelDestination(IpAddressBuilder.getDefaultInstance(ITMConstants.DUMMY_IP_ADDRESS))
361 .setTunnelSource(IpAddressBuilder.getDefaultInstance(ITMConstants.DUMMY_IP_ADDRESS)).setInternal(true)
362 .setMonitorEnabled(false).setTunnelInterfaceType(TunnelTypeLogicalGroup.class)
363 .setTunnelRemoteIpFlow(false).build();
364 builder.addAugmentation(IfTunnel.class, tunnel);
365 return builder.build();
368 public static Interface buildTunnelInterface(BigInteger dpn, String ifName, String desc, boolean enabled,
369 Class<? extends TunnelTypeBase> tunType, IpAddress localIp,
370 IpAddress remoteIp, IpAddress gatewayIp, Integer vlanId,
371 boolean internal, Boolean monitorEnabled,
372 Class<? extends TunnelMonitoringTypeBase> monitorProtocol,
373 Integer monitorInterval, boolean useOfTunnel,
374 List<TunnelOptions> tunOptions) {
376 return buildTunnelInterface(dpn, ifName, desc, enabled, tunType, localIp, remoteIp, gatewayIp, vlanId,
377 internal, monitorEnabled, monitorProtocol, monitorInterval, useOfTunnel, null,
381 public static Interface buildTunnelInterface(BigInteger dpn, String ifName, String desc, boolean enabled,
382 Class<? extends TunnelTypeBase> tunType, IpAddress localIp,
383 IpAddress remoteIp, IpAddress gatewayIp, Integer vlanId,
384 boolean internal, Boolean monitorEnabled,
385 Class<? extends TunnelMonitoringTypeBase> monitorProtocol,
386 Integer monitorInterval, boolean useOfTunnel, String parentIfaceName,
387 List<TunnelOptions> tunnelOptions) {
388 InterfaceBuilder builder = new InterfaceBuilder().withKey(new InterfaceKey(ifName)).setName(ifName)
389 .setDescription(desc).setEnabled(enabled).setType(Tunnel.class);
390 ParentRefs parentRefs =
391 new ParentRefsBuilder().setDatapathNodeIdentifier(dpn).setParentInterface(parentIfaceName).build();
392 builder.addAugmentation(ParentRefs.class, parentRefs);
393 Long monitoringInterval = null;
395 IfL2vlan l2vlan = new IfL2vlanBuilder().setVlanId(new VlanId(vlanId)).build();
396 builder.addAugmentation(IfL2vlan.class, l2vlan);
398 LOG.debug("buildTunnelInterface: monitorProtocol = {} and monitorInterval = {}",
399 monitorProtocol.getName(),monitorInterval);
401 if (monitorInterval != null) {
402 monitoringInterval = monitorInterval.longValue();
405 IfTunnel tunnel = new IfTunnelBuilder().setTunnelDestination(remoteIp).setTunnelGateway(gatewayIp)
406 .setTunnelSource(localIp).setTunnelInterfaceType(tunType).setInternal(internal)
407 .setMonitorEnabled(monitorEnabled).setMonitorProtocol(monitorProtocol)
408 .setMonitorInterval(monitoringInterval).setTunnelRemoteIpFlow(useOfTunnel)
409 .setTunnelOptions(tunnelOptions)
411 builder.addAugmentation(IfTunnel.class, tunnel);
412 return builder.build();
415 public static Interface buildHwTunnelInterface(String tunnelIfName, String desc, boolean enabled, String topoId,
416 String nodeId, Class<? extends TunnelTypeBase> tunType,
417 IpAddress srcIp, IpAddress destIp, IpAddress gwIp,
418 Boolean monitorEnabled,
419 Class<? extends TunnelMonitoringTypeBase> monitorProtocol,
420 Integer monitorInterval) {
421 InterfaceBuilder builder = new InterfaceBuilder().withKey(new InterfaceKey(tunnelIfName))
422 .setName(tunnelIfName).setDescription(desc).setEnabled(enabled).setType(Tunnel.class);
423 List<NodeIdentifier> nodeIds = new ArrayList<>();
424 NodeIdentifier hwNode = new NodeIdentifierBuilder().withKey(new NodeIdentifierKey(topoId))
425 .setTopologyId(topoId).setNodeId(nodeId).build();
427 ParentRefs parent = new ParentRefsBuilder().setNodeIdentifier(nodeIds).build();
428 builder.addAugmentation(ParentRefs.class, parent);
429 IfTunnel tunnel = new IfTunnelBuilder().setTunnelDestination(destIp).setTunnelGateway(gwIp)
430 .setTunnelSource(srcIp).setMonitorEnabled(monitorEnabled == null || monitorEnabled)
431 .setMonitorProtocol(monitorProtocol == null ? ITMConstants.DEFAULT_MONITOR_PROTOCOL : monitorProtocol)
432 .setMonitorInterval(DEFAULT_MONITORING_INTERVAL).setTunnelInterfaceType(tunType).setInternal(false)
434 builder.addAugmentation(IfTunnel.class, tunnel);
435 LOG.trace("iftunnel {} built from hwvtep {} ", tunnel, nodeId);
436 return builder.build();
439 public static InternalTunnel buildInternalTunnel(BigInteger srcDpnId, BigInteger dstDpnId,
440 Class<? extends TunnelTypeBase> tunType,
441 String trunkInterfaceName) {
442 return new InternalTunnelBuilder().withKey(new InternalTunnelKey(dstDpnId, srcDpnId, tunType))
443 .setDestinationDPN(dstDpnId)
444 .setSourceDPN(srcDpnId).setTransportType(tunType)
445 .setTunnelInterfaceNames(Collections.singletonList(trunkInterfaceName)).build();
448 public static ExternalTunnel buildExternalTunnel(String srcNode, String dstNode,
449 Class<? extends TunnelTypeBase> tunType,
450 String trunkInterfaceName) {
451 return new ExternalTunnelBuilder().withKey(
452 new ExternalTunnelKey(dstNode, srcNode, tunType))
453 .setSourceDevice(srcNode).setDestinationDevice(dstNode)
454 .setTunnelInterfaceName(trunkInterfaceName)
455 .setTransportType(tunType).build();
458 private static String getUniqueIdString(String idKey) {
459 return UUID.nameUUIDFromBytes(idKey.getBytes(StandardCharsets.UTF_8)).toString().substring(0, 12)
463 public static List<DPNTEPsInfo> getDpnTepListFromDpnId(DPNTEPsInfoCache dpnTEPsInfoCache, List<BigInteger> dpnIds) {
464 Collection<DPNTEPsInfo> meshedDpnList = dpnTEPsInfoCache.getAllPresent();
465 List<DPNTEPsInfo> cfgDpnList = new ArrayList<>();
466 for (BigInteger dpnId : dpnIds) {
467 for (DPNTEPsInfo teps : meshedDpnList) {
468 if (dpnId.equals(teps.getDPNID())) {
469 cfgDpnList.add(teps);
477 @SuppressWarnings("checkstyle:IllegalCatch")
478 public static void addTerminatingServiceTable(TypedReadWriteTransaction<Configuration> tx,
479 BigInteger dpnId, IMdsalApiManager mdsalManager) {
480 LOG.trace("Installing PUNT to Controller flow in DPN {} ", dpnId);
481 List<ActionInfo> listActionInfo = new ArrayList<>();
482 listActionInfo.add(new ActionPuntToController());
485 List<MatchInfo> mkMatches = new ArrayList<>();
487 mkMatches.add(new MatchTunnelId(BigInteger.valueOf(ITMConstants.LLDP_SERVICE_ID)));
489 List<InstructionInfo> mkInstructions = new ArrayList<>();
490 mkInstructions.add(new InstructionApplyActions(listActionInfo));
492 FlowEntity terminatingServiceTableFlowEntity = MDSALUtil
493 .buildFlowEntity(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE,
494 getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE, ITMConstants.LLDP_SERVICE_ID),
495 5, String.format("%s:%d","ITM Flow Entry ", ITMConstants.LLDP_SERVICE_ID), 0, 0,
496 ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(ITMConstants.LLDP_SERVICE_ID)),
497 mkMatches, mkInstructions);
498 mdsalManager.addFlow(tx, terminatingServiceTableFlowEntity);
499 } catch (Exception e) {
500 LOG.error("Error while setting up Table 36 for {}", dpnId, e);
504 @SuppressWarnings("checkstyle:IllegalCatch")
505 public static void removeTerminatingServiceTable(TypedReadWriteTransaction<Configuration> tx,
506 BigInteger dpnId, IMdsalApiManager mdsalManager) {
507 LOG.trace("Removing PUNT to Controller flow in DPN {} ", dpnId);
510 mdsalManager.removeFlow(tx, dpnId,
511 getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE, ITMConstants.LLDP_SERVICE_ID),
512 NwConstants.INTERNAL_TUNNEL_TABLE);
513 } catch (Exception e) {
514 LOG.error("Error while setting up Table 36 for {}", dpnId, e);
518 private static String getFlowRef(long termSvcTable, int svcId) {
519 return String.valueOf(termSvcTable) + svcId;
522 public static InstanceIdentifier<VtepConfigSchema> getVtepConfigSchemaIdentifier(String schemaName) {
523 return InstanceIdentifier.builder(VtepConfigSchemas.class)
524 .child(VtepConfigSchema.class, new VtepConfigSchemaKey(schemaName)).build();
527 public static InstanceIdentifier<VtepConfigSchema> getVtepConfigSchemaIdentifier() {
528 return InstanceIdentifier.builder(VtepConfigSchemas.class).child(VtepConfigSchema.class).build();
531 public static InstanceIdentifier<VtepConfigSchemas> getVtepConfigSchemasIdentifier() {
532 return InstanceIdentifier.builder(VtepConfigSchemas.class).build();
535 public static InstanceIdentifier<VtepIpPool> getVtepIpPoolIdentifier(String subnetCidr) {
536 return InstanceIdentifier.builder(VtepIpPools.class).child(VtepIpPool.class, new VtepIpPoolKey(subnetCidr))
540 public static VtepConfigSchema validateForAddVtepConfigSchema(VtepConfigSchema schema,
541 List<VtepConfigSchema> existingSchemas) {
542 VtepConfigSchema validSchema = validateVtepConfigSchema(schema);
543 for (VtepConfigSchema existingSchema : emptyIfNull(existingSchemas)) {
544 if (!StringUtils.equalsIgnoreCase(schema.getSchemaName(), existingSchema.getSchemaName())
545 && schema.getSubnet().equals(existingSchema.getSubnet())) {
546 String subnetCidr = getSubnetCidrAsString(schema.getSubnet());
547 Preconditions.checkArgument(false, "VTEP schema with subnet [" + subnetCidr
548 + "] already exists. Multiple VTEP schemas with same subnet is not allowed.");
551 if (isNotEmpty(getDpnIdList(validSchema.getDpnIds()))) {
552 String tzone = validSchema.getTransportZoneName();
553 List<BigInteger> lstDpns = getConflictingDpnsAlreadyConfiguredWithTz(validSchema.getSchemaName(), tzone,
554 getDpnIdList(validSchema.getDpnIds()), existingSchemas);
555 if (!lstDpns.isEmpty()) {
556 Preconditions.checkArgument(false, "DPN's " + lstDpns + " already configured for transport zone "
557 + tzone + ". Only one end point per transport Zone per Dpn is allowed.");
559 if (schema.getTunnelType().equals(TunnelTypeGre.class)) {
560 validateForSingleGreTep(validSchema.getSchemaName(), getDpnIdList(validSchema.getDpnIds()),
567 private static void validateForSingleGreTep(String schemaName, List<BigInteger> lstDpnsForAdd,
568 List<VtepConfigSchema> existingSchemas) {
569 for (VtepConfigSchema existingSchema : emptyIfNull(existingSchemas)) {
570 if (TunnelTypeGre.class.equals(existingSchema.getTunnelType())
571 && !StringUtils.equalsIgnoreCase(schemaName, existingSchema.getSchemaName())) {
572 List<BigInteger> lstConflictingDpns = new ArrayList<>(getDpnIdList(existingSchema.getDpnIds()));
573 lstConflictingDpns.retainAll(emptyIfNull(lstDpnsForAdd));
574 if (!lstConflictingDpns.isEmpty()) {
575 String errMsg = "DPN's " + lstConflictingDpns
576 + " already configured with GRE TEP. Mutiple GRE TEP's on a single DPN are not allowed.";
577 Preconditions.checkArgument(false, errMsg);
583 public static VtepConfigSchema validateVtepConfigSchema(VtepConfigSchema schema) {
584 Preconditions.checkNotNull(schema);
585 Preconditions.checkArgument(StringUtils.isNotBlank(schema.getSchemaName()));
586 Preconditions.checkArgument(StringUtils.isNotBlank(schema.getPortName()));
587 Preconditions.checkArgument(schema.getVlanId() >= 0 && schema.getVlanId() < 4095,
588 "Invalid VLAN ID, range (0-4094)");
589 Preconditions.checkArgument(StringUtils.isNotBlank(schema.getTransportZoneName()));
590 Preconditions.checkNotNull(schema.getSubnet());
591 String subnetCidr = getSubnetCidrAsString(schema.getSubnet());
592 SubnetUtils subnetUtils = new SubnetUtils(subnetCidr);
593 IpAddress gatewayIp = schema.getGatewayIp();
594 if (gatewayIp != null) {
595 String strGatewayIp = String.valueOf(gatewayIp.getValue());
596 if (!strGatewayIp.equals(ITMConstants.DUMMY_IP_ADDRESS) && !subnetUtils.getInfo().isInRange(strGatewayIp)) {
597 Preconditions.checkArgument(false, "Gateway IP address " + strGatewayIp
598 + " is not in subnet range " + subnetCidr);
601 ItmUtils.getExcludeIpAddresses(schema.getExcludeIpFilter(), subnetUtils.getInfo());
602 return new VtepConfigSchemaBuilder(schema).setTunnelType(schema.getTunnelType()).build();
605 public static String validateTunnelType(String tunnelType) {
606 if (tunnelType == null) {
607 tunnelType = ITMConstants.TUNNEL_TYPE_VXLAN;
609 tunnelType = StringUtils.upperCase(tunnelType);
610 String error = "Invalid tunnel type. Valid values: "
611 + ITMConstants.TUNNEL_TYPE_VXLAN + " | " + ITMConstants.TUNNEL_TYPE_GRE;
612 Preconditions.checkArgument(ITMConstants.TUNNEL_TYPE_VXLAN.equals(tunnelType)
613 || ITMConstants.TUNNEL_TYPE_GRE.equals(tunnelType), error);
618 private static List<BigInteger> getConflictingDpnsAlreadyConfiguredWithTz(String schemaName, String tzone,
619 List<BigInteger> lstDpns,
620 List<VtepConfigSchema> existingSchemas) {
621 List<BigInteger> lstConflictingDpns = new ArrayList<>();
622 for (VtepConfigSchema schema : emptyIfNull(existingSchemas)) {
623 if (!StringUtils.equalsIgnoreCase(schemaName, schema.getSchemaName())
624 && StringUtils.equals(schema.getTransportZoneName(), tzone)) {
625 lstConflictingDpns = new ArrayList<>(getDpnIdList(schema.getDpnIds()));
626 lstConflictingDpns.retainAll(lstDpns);
627 if (!lstConflictingDpns.isEmpty()) {
632 return lstConflictingDpns;
635 public static VtepConfigSchema constructVtepConfigSchema(String schemaName, String portName, Integer vlanId,
636 String subnetMask, String gatewayIp, String transportZone,
637 String tunnelType, List<BigInteger> dpnIds,
638 String excludeIpFilter) {
639 IpAddress gatewayIpObj = StringUtils.isBlank(gatewayIp) ? null : IpAddressBuilder.getDefaultInstance(gatewayIp);
640 IpPrefix subnet = StringUtils.isBlank(subnetMask) ? null : IpPrefixBuilder.getDefaultInstance(subnetMask);
641 Class<? extends TunnelTypeBase> tunType ;
642 if (tunnelType.equals(ITMConstants.TUNNEL_TYPE_VXLAN)) {
643 tunType = TunnelTypeVxlan.class ;
645 tunType = TunnelTypeGre.class ;
647 VtepConfigSchemaBuilder schemaBuilder = new VtepConfigSchemaBuilder().setSchemaName(schemaName)
648 .setPortName(portName).setVlanId(vlanId).setSubnet(subnet).setGatewayIp(gatewayIpObj)
649 .setTransportZoneName(transportZone).setTunnelType(tunType).setDpnIds(getDpnIdsListFromBigInt(dpnIds))
650 .setExcludeIpFilter(excludeIpFilter);
651 return schemaBuilder.build();
654 public static List<IpAddress> getExcludeIpAddresses(String excludeIpFilter, SubnetInfo subnetInfo) {
655 final List<IpAddress> lstIpAddress = new ArrayList<>();
656 if (StringUtils.isBlank(excludeIpFilter)) {
659 final String[] arrIps = StringUtils.split(excludeIpFilter, ',');
660 for (String ip : arrIps) {
661 if (StringUtils.countMatches(ip, "-") == 1) {
662 final String[] arrIpRange = StringUtils.split(ip, '-');
663 String strStartIp = StringUtils.trim(arrIpRange[0]);
664 String strEndIp = StringUtils.trim(arrIpRange[1]);
665 Preconditions.checkArgument(InetAddresses.isInetAddress(strStartIp),
666 "Invalid exclude IP filter: invalid IP address value " + strStartIp);
667 Preconditions.checkArgument(InetAddresses.isInetAddress(strEndIp),
668 "Invalid exclude IP filter: invalid IP address value " + strEndIp);
669 Preconditions.checkArgument(subnetInfo.isInRange(strStartIp),
670 "Invalid exclude IP filter: IP address [" + strStartIp
671 + "] not in subnet range " + subnetInfo.getCidrSignature());
672 Preconditions.checkArgument(subnetInfo.isInRange(strEndIp),
673 "Invalid exclude IP filter: IP address [" + strEndIp
674 + "] not in subnet range " + subnetInfo.getCidrSignature());
675 int startIp = subnetInfo.asInteger(strStartIp);
676 int endIp = subnetInfo.asInteger(strEndIp);
678 Preconditions.checkArgument(startIp < endIp,
679 "Invalid exclude IP filter: Invalid range [" + ip + "] ");
680 for (int iter = startIp; iter <= endIp; iter++) {
681 String ipAddress = ipFormat(toIpArray(iter));
682 validateAndAddIpAddressToList(subnetInfo, lstIpAddress, ipAddress);
685 validateAndAddIpAddressToList(subnetInfo, lstIpAddress, ip);
691 private static void validateAndAddIpAddressToList(SubnetInfo subnetInfo, final List<IpAddress> lstIpAddress,
693 String ip = StringUtils.trim(ipAddress);
694 Preconditions.checkArgument(InetAddresses.isInetAddress(ip),
695 "Invalid exclude IP filter: invalid IP address value " + ip);
696 Preconditions.checkArgument(subnetInfo.isInRange(ip),
697 "Invalid exclude IP filter: IP address [" + ip + "] not in subnet range "
698 + subnetInfo.getCidrSignature());
699 lstIpAddress.add(IpAddressBuilder.getDefaultInstance(ip));
702 private static int[] toIpArray(int val) {
703 int[] ret = new int[4];
704 for (int iter = 3; iter >= 0; --iter) {
705 ret[iter] |= val >>> 8 * (3 - iter) & 0xff;
710 private static String ipFormat(int[] octets) {
711 StringBuilder str = new StringBuilder();
712 for (int iter = 0; iter < octets.length; ++iter) {
713 str.append(octets[iter]);
714 if (iter != octets.length - 1) {
718 return str.toString();
721 public static VtepConfigSchema validateForUpdateVtepSchema(String schemaName, List<BigInteger> lstDpnsForAdd,
722 List<BigInteger> lstDpnsForDelete,
723 IITMProvider itmProvider) {
724 Preconditions.checkArgument(StringUtils.isNotBlank(schemaName));
725 if ((lstDpnsForAdd == null || lstDpnsForAdd.isEmpty())
726 && (lstDpnsForDelete == null || lstDpnsForDelete.isEmpty())) {
727 Preconditions.checkArgument(false,
728 "DPN ID list for add | delete is null or empty in schema " + schemaName);
730 VtepConfigSchema schema = itmProvider.getVtepConfigSchema(schemaName);
731 if (schema == null) {
732 Preconditions.checkArgument(false, "Specified VTEP Schema [" + schemaName
733 + "] doesn't exists!");
735 List<BigInteger> existingDpnIds = getDpnIdList(schema.getDpnIds());
736 if (isNotEmpty(lstDpnsForAdd)) {
737 List<BigInteger> lstAlreadyExistingDpns = new ArrayList<>(existingDpnIds);
738 lstAlreadyExistingDpns.retainAll(lstDpnsForAdd);
739 Preconditions.checkArgument(lstAlreadyExistingDpns.isEmpty(),
740 "DPN ID's " + lstAlreadyExistingDpns
741 + " already exists in VTEP schema [" + schemaName + "]");
742 if (schema.getTunnelType().equals(TunnelTypeGre.class)) {
743 validateForSingleGreTep(schema.getSchemaName(), lstDpnsForAdd, itmProvider.getAllVtepConfigSchemas());
746 if (isNotEmpty(lstDpnsForDelete)) {
747 if (existingDpnIds.isEmpty()) {
748 String builder = "DPN ID's " + lstDpnsForDelete
749 + " specified for delete from VTEP schema [" + schemaName
750 + "] are not configured in the schema.";
751 Preconditions.checkArgument(false, builder);
752 } else if (!existingDpnIds.containsAll(lstDpnsForDelete)) {
753 List<BigInteger> lstConflictingDpns = new ArrayList<>(lstDpnsForDelete);
754 lstConflictingDpns.removeAll(existingDpnIds);
755 String builder = "DPN ID's " + lstConflictingDpns
756 + " specified for delete from VTEP schema [" + schemaName
757 + "] are not configured in the schema.";
758 Preconditions.checkArgument(false, builder);
764 public static String getSubnetCidrAsString(IpPrefix subnet) {
765 return subnet == null ? StringUtils.EMPTY : String.valueOf(subnet.getValue());
768 public static <T> List<T> emptyIfNull(List<T> list) {
769 return list == null ? Collections.emptyList() : list;
772 public static <T> boolean isEmpty(Collection<T> collection) {
773 return collection == null || collection.isEmpty();
776 public static <T> boolean isNotEmpty(Collection<T> collection) {
777 return !isEmpty(collection);
781 public static HwVtep createHwVtepObject(String topoId, String nodeId, IpAddress ipAddress, IpPrefix ipPrefix,
782 IpAddress gatewayIP, int vlanID,
783 Class<? extends TunnelTypeBase> tunneltype, TransportZone transportZone) {
784 HwVtep hwVtep = new HwVtep();
785 hwVtep.setGatewayIP(gatewayIP);
786 hwVtep.setHwIp(ipAddress);
787 hwVtep.setIpPrefix(ipPrefix);
788 hwVtep.setNodeId(nodeId);
789 hwVtep.setTopoId(topoId);
790 hwVtep.setTransportZone(transportZone.getZoneName());
791 hwVtep.setTunnelType(tunneltype);
792 hwVtep.setVlanID(vlanID);
796 public static String getHwParentIf(String topoId, String srcNodeid) {
797 return String.format("%s:%s", topoId, srcNodeid);
801 * Synchronous blocking write to data store.
804 * {@link SingleTransactionDataBroker#syncWrite(DataBroker, LogicalDatastoreType, InstanceIdentifier, DataObject)}
808 public static <T extends DataObject> void syncWrite(LogicalDatastoreType datastoreType,
809 InstanceIdentifier<T> path, T data, DataBroker broker) {
810 WriteTransaction tx = broker.newWriteOnlyTransaction();
811 tx.put(datastoreType, path, data, true);
814 } catch (InterruptedException | ExecutionException e) {
815 LOG.error("ITMUtils:SyncWrite , Error writing to datastore (path, data) : ({}, {})", path, data);
816 throw new RuntimeException(e.getMessage(), e);
821 public static List<BigInteger> getDpnIdList(List<DpnIds> dpnIds) {
822 List<BigInteger> dpnList = new ArrayList<>() ;
823 for (DpnIds dpn : dpnIds) {
824 dpnList.add(dpn.getDPN()) ;
829 public static List<DpnIds> getDpnIdsListFromBigInt(List<BigInteger> dpnIds) {
830 List<DpnIds> dpnIdList = new ArrayList<>();
831 DpnIdsBuilder builder = new DpnIdsBuilder();
832 for (BigInteger dpnId : dpnIds) {
833 dpnIdList.add(builder.withKey(new DpnIdsKey(dpnId)).setDPN(dpnId).build());
838 public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces
839 .rev140508.interfaces.state.Interface> buildStateInterfaceId(
840 String interfaceName) {
841 return InstanceIdentifier.builder(InterfacesState.class)
842 .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
843 .state.Interface.class,
844 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces
845 .rev140508.interfaces.state.InterfaceKey(
846 interfaceName)).build();
850 public static List<String> getInternalTunnelInterfaces(DataBroker dataBroker) {
851 List<String> tunnelList = new ArrayList<>();
852 Collection<String> internalInterfaces = ITM_CACHE.getAllInternalInterfaces();
853 if (internalInterfaces.isEmpty()) {
854 updateTunnelsCache(dataBroker);
855 internalInterfaces = ITM_CACHE.getAllInternalInterfaces();
857 LOG.debug("ItmUtils.getTunnelList Cache Internal Interfaces size: {} ", internalInterfaces.size());
858 tunnelList.addAll(internalInterfaces);
859 LOG.trace("ItmUtils.getTunnelList Internal: {}", tunnelList);
863 public static List<InternalTunnel> getInternalTunnelsFromCache(DataBroker dataBroker) {
864 List<InternalTunnel> tunnelList = new ArrayList<>();
865 Collection<InternalTunnel> internalInterfaces = ITM_CACHE.getAllInternalTunnel();
866 if (internalInterfaces.isEmpty()) {
867 updateTunnelsCache(dataBroker);
868 internalInterfaces = ITM_CACHE.getAllInternalTunnel();
870 LOG.debug("Number of Internal Tunnel Interfaces in cache: {} ", internalInterfaces.size());
871 tunnelList.addAll(internalInterfaces);
872 LOG.trace("List of Internal Tunnels: {}", tunnelList);
876 public static List<String> getTunnelsofTzone(List<HwVtep> hwVteps, String tzone, DataBroker dataBroker,
877 Boolean hwVtepsExist) {
878 List<String> tunnels = new ArrayList<>();
879 InstanceIdentifier<TransportZone> path = InstanceIdentifier.builder(TransportZones.class)
880 .child(TransportZone.class, new TransportZoneKey(tzone)).build();
881 Optional<TransportZone> transportZoneOptional =
882 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
883 if (transportZoneOptional.isPresent()) {
884 TransportZone transportZone = transportZoneOptional.get();
885 Class<? extends TunnelTypeBase> tunType = transportZone.getTunnelType();
886 if (transportZone.getSubnets() != null && !transportZone.getSubnets().isEmpty()) {
887 for (Subnets sub : transportZone.getSubnets()) {
888 if (sub.getVteps() != null && !sub.getVteps().isEmpty()) {
889 for (Vteps vtepLocal : sub.getVteps()) {
890 for (Vteps vtepRemote : sub.getVteps()) {
891 if (!vtepLocal.equals(vtepRemote)) {
892 InternalTunnelKey key = new InternalTunnelKey(vtepRemote.getDpnId(),
893 vtepLocal.getDpnId(), tunType);
894 InstanceIdentifier<InternalTunnel> intIID =
895 InstanceIdentifier.builder(TunnelList.class)
896 .child(InternalTunnel.class, key).build();
897 Optional<InternalTunnel> tunnelsOptional =
898 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, intIID, dataBroker);
899 if (tunnelsOptional.isPresent()) {
900 List<String> tunnelInterfaceNames = tunnelsOptional
901 .get().getTunnelInterfaceNames();
902 if (tunnelInterfaceNames != null && !tunnelInterfaceNames.isEmpty()) {
903 String tunnelInterfaceName = tunnelInterfaceNames.get(0);
904 LOG.trace("Internal Tunnel added {}", tunnelInterfaceName);
905 tunnels.add(tunnelInterfaceName);
910 if (hwVteps != null && !hwVteps.isEmpty()) {
911 for (HwVtep hwVtep : hwVteps) {
912 tunnels.add(getExtTunnel(hwVtep.getNodeId(), vtepLocal.getDpnId().toString(),
913 tunType, dataBroker));
914 tunnels.add(getExtTunnel(vtepLocal.getDpnId().toString(), hwVtep.getNodeId(),
915 tunType, dataBroker));
923 for (HwVtep hwVtep : hwVteps) {
924 for (HwVtep hwVtepOther : hwVteps) {
925 if (!hwVtep.getHwIp().equals(hwVtepOther.getHwIp())) {
926 tunnels.add(getExtTunnel(hwVtep.getNodeId(), hwVtepOther.getNodeId(),
927 tunType, dataBroker));
928 tunnels.add(getExtTunnel(hwVtepOther.getNodeId(), hwVtep.getNodeId(),
929 tunType, dataBroker));
938 public static List<String> getInternalTunnelsofTzone(String tzone, DataBroker dataBroker) {
939 List<String> tunnels = new ArrayList<>();
940 LOG.trace("Getting internal tunnels of {}",tzone);
941 InstanceIdentifier<TransportZone> path = InstanceIdentifier.builder(TransportZones.class)
942 .child(TransportZone.class, new TransportZoneKey(tzone)).build();
943 Optional<TransportZone> transportZoneOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
945 if (transportZoneOptional.isPresent()) {
946 TransportZone transportZone = transportZoneOptional.get();
947 if (transportZone.getSubnets() != null && !transportZone.getSubnets().isEmpty()) {
948 for (Subnets sub : transportZone.getSubnets()) {
949 if (sub.getVteps() != null && !sub.getVteps().isEmpty()) {
950 for (Vteps vtepLocal : sub.getVteps()) {
951 for (Vteps vtepRemote : sub.getVteps()) {
952 if (!vtepLocal.equals(vtepRemote)) {
953 InternalTunnelKey key =
954 new InternalTunnelKey(vtepRemote.getDpnId(), vtepLocal.getDpnId(),
955 transportZone.getTunnelType());
956 InstanceIdentifier<InternalTunnel> intIID =
957 InstanceIdentifier.builder(TunnelList.class)
958 .child(InternalTunnel.class, key).build();
959 Optional<InternalTunnel> tunnelsOptional =
960 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, intIID, dataBroker);
961 if (tunnelsOptional.isPresent()) {
962 List<String> tunnelInterfaceNames = tunnelsOptional.get()
963 .getTunnelInterfaceNames();
964 if (tunnelInterfaceNames != null && !tunnelInterfaceNames.isEmpty()) {
965 String tunnelInterfaceName = tunnelInterfaceNames.get(0);
966 LOG.trace("Internal Tunnel added {}", tunnelInterfaceName);
967 tunnels.add(tunnelInterfaceName);
980 private static String getExtTunnel(String nodeId, String dpId,Class<? extends TunnelTypeBase> tunType, DataBroker
982 LOG.trace("getting ext tunnel for {} and dpId {}",nodeId,dpId);
983 ExternalTunnelKey key = getExternalTunnelKey(dpId, nodeId, tunType);
984 InstanceIdentifier<ExternalTunnel> intIID = InstanceIdentifier.builder(ExternalTunnelList.class)
985 .child(ExternalTunnel.class, key).build();
986 Optional<ExternalTunnel> tunnelsOptional =
987 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, intIID, dataBroker);
988 if (tunnelsOptional.isPresent()) {
989 String tunnelInterfaceName = tunnelsOptional.get().getTunnelInterfaceName();
990 LOG.trace("ext tunnel returned {} ", tunnelInterfaceName);
991 return tunnelInterfaceName;
996 @SuppressFBWarnings("RV_CHECK_FOR_POSITIVE_INDEXOF")
997 public static ExternalTunnelKey getExternalTunnelKey(String dst , String src,
998 Class<? extends TunnelTypeBase> tunType) {
999 final int srcIndex = src.indexOf("physicalswitch");
1001 src = src.substring(0, srcIndex - 1);
1003 final int dstIndex = dst.indexOf("physicalswitch");
1005 dst = dst.substring(0, dstIndex - 1);
1007 return new ExternalTunnelKey(dst, src, tunType);
1010 public static List<TunnelEndPoints> getTEPsForDpn(BigInteger srcDpn, Collection<DPNTEPsInfo> dpnList) {
1011 for (DPNTEPsInfo dpn : dpnList) {
1012 if (dpn.getDPNID().equals(srcDpn)) {
1013 return dpn.getTunnelEndPoints() ;
1019 public static List<InternalTunnel> getAllInternalTunnels(DataBroker dataBroker) {
1020 List<InternalTunnel> result = null;
1021 InstanceIdentifier<TunnelList> iid = InstanceIdentifier.builder(TunnelList.class).build();
1022 Optional<TunnelList> tunnelList = read(LogicalDatastoreType.CONFIGURATION, iid, dataBroker);
1024 if (tunnelList.isPresent()) {
1025 result = tunnelList.get().getInternalTunnel();
1027 if (result == null) {
1028 result = Collections.emptyList();
1033 public static InternalTunnel getInternalTunnel(String interfaceName, DataBroker broker) {
1034 InternalTunnel internalTunnel = ITM_CACHE.getInternalTunnel(interfaceName);
1035 if (internalTunnel == null) {
1036 updateTunnelsCache(broker);
1037 internalTunnel = ITM_CACHE.getInternalTunnel(interfaceName);
1039 return internalTunnel;
1042 public static ExternalTunnel getExternalTunnel(String interfaceName, DataBroker broker) {
1043 ExternalTunnel externalTunnel = ITM_CACHE.getExternalTunnel(interfaceName);
1044 if (externalTunnel == null) {
1045 updateTunnelsCache(broker);
1046 externalTunnel = ITM_CACHE.getExternalTunnel(interfaceName);
1048 return externalTunnel;
1051 private static List<ExternalTunnel> getAllExternalTunnels(DataBroker dataBroker) {
1052 List<ExternalTunnel> result = null;
1053 InstanceIdentifier<ExternalTunnelList> iid = InstanceIdentifier.builder(ExternalTunnelList.class).build();
1054 Optional<ExternalTunnelList> tunnelList = read(LogicalDatastoreType.CONFIGURATION, iid, dataBroker);
1055 if (tunnelList.isPresent()) {
1056 result = tunnelList.get().getExternalTunnel();
1058 if (result == null) {
1059 result = Collections.emptyList();
1064 public static String convertTunnelTypetoString(Class<? extends TunnelTypeBase> tunType) {
1065 String tunnelType = ITMConstants.TUNNEL_TYPE_VXLAN;
1066 if (tunType.equals(TunnelTypeVxlan.class)) {
1067 tunnelType = ITMConstants.TUNNEL_TYPE_VXLAN ;
1068 } else if (tunType.equals(TunnelTypeGre.class)) {
1069 tunnelType = ITMConstants.TUNNEL_TYPE_GRE ;
1070 } else if (tunType.equals(TunnelTypeMplsOverGre.class)) {
1071 tunnelType = ITMConstants.TUNNEL_TYPE_MPLSoGRE;
1072 } else if (tunType.equals(TunnelTypeLogicalGroup.class)) {
1073 tunnelType = ITMConstants.TUNNEL_TYPE_LOGICAL_GROUP_VXLAN;
1079 public static boolean isItmIfType(Class<? extends InterfaceType> ifType) {
1080 return ifType != null && ifType.isAssignableFrom(Tunnel.class);
1083 public static StateTunnelListKey getTunnelStateKey(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
1084 .interfaces.rev140508.interfaces.state.Interface iface) {
1085 StateTunnelListKey key = null;
1086 if (isItmIfType(iface.getType())) {
1087 key = new StateTunnelListKey(iface.getName());
1092 private static void updateTunnelsCache(DataBroker broker) {
1093 List<InternalTunnel> internalTunnels = getAllInternalTunnels(broker);
1094 for (InternalTunnel tunnel : internalTunnels) {
1095 ITM_CACHE.addInternalTunnel(tunnel);
1097 List<ExternalTunnel> externalTunnels = getAllExternalTunnels(broker);
1098 for (ExternalTunnel tunnel : externalTunnels) {
1099 ITM_CACHE.addExternalTunnel(tunnel);
1103 public static Interface getInterface(
1104 String name, IInterfaceManager ifaceManager) {
1105 Interface result = ITM_CACHE.getInterface(name);
1106 if (result == null) {
1107 result = ifaceManager.getInterfaceInfoFromConfigDataStore(name);
1108 if (result != null) {
1109 ITM_CACHE.addInterface(result);
1115 public static List<DcGatewayIp> getDcGatewayIpList(DataBroker broker) {
1116 InstanceIdentifier<DcGatewayIpList> dcGatewayIpListid =
1117 InstanceIdentifier.builder(DcGatewayIpList.class).build();
1118 Optional<DcGatewayIpList> dcGatewayIpListConfig =
1119 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, dcGatewayIpListid, broker);
1120 if (dcGatewayIpListConfig.isPresent()) {
1121 DcGatewayIpList containerList = dcGatewayIpListConfig.get();
1122 if (containerList != null) {
1123 return containerList.getDcGatewayIp();
1129 public static boolean falseIfNull(Boolean value) {
1130 return value == null ? false : value;
1133 public static <T> List<T> getIntersection(List<T> list1, List<T> list2) {
1134 List<T> list = new ArrayList<>();
1135 for (T iter : list1) {
1136 if (list2.contains(iter)) {
1140 LOG.debug(" getIntersection - L1 {}, L2 - {}, Intersection - {}", list1, list2, list);
1144 public static void addTransportZoneMembership(List<TzMembership> zones, String zoneName) {
1145 zones.add(new TzMembershipBuilder().setZoneName(zoneName).build());
1148 public static List<TzMembership> createTransportZoneMembership(String zoneName) {
1149 List<TzMembership> zones = new ArrayList<>();
1150 zones.add(new TzMembershipBuilder().setZoneName(zoneName).build());
1155 * Gets the transport zone in TepsNotHosted list in the Operational Datastore, based on transport zone name.
1157 * @param unknownTz transport zone name
1159 * @param dataBroker data broker handle to perform read operations on Oper datastore
1161 * @return the TepsInNotHostedTransportZone object in the TepsNotHosted list in Oper DS
1163 public static TepsInNotHostedTransportZone getUnknownTransportZoneFromITMOperDS(
1164 String unknownTz, DataBroker dataBroker) {
1165 InstanceIdentifier<TepsInNotHostedTransportZone> unknownTzPath =
1166 InstanceIdentifier.builder(NotHostedTransportZones.class)
1167 .child(TepsInNotHostedTransportZone.class,
1168 new TepsInNotHostedTransportZoneKey(unknownTz)).build();
1169 Optional<TepsInNotHostedTransportZone> unknownTzOptional =
1170 ItmUtils.read(LogicalDatastoreType.OPERATIONAL, unknownTzPath, dataBroker);
1171 if (unknownTzOptional.isPresent()) {
1172 return unknownTzOptional.get();
1178 * Gets the bridge datapath ID from Network topology Node's OvsdbBridgeAugmentation, in the Operational DS.
1180 * @param node Network Topology Node
1182 * @param bridge bridge name
1184 * @param dataBroker data broker handle to perform operations on datastore
1186 * @return the datapath ID of bridge in string form
1188 public static String getBridgeDpid(Node node, String bridge, DataBroker dataBroker) {
1189 OvsdbBridgeAugmentation ovsdbBridgeAugmentation = null;
1190 Node bridgeNode = null;
1191 String datapathId = null;
1193 NodeId ovsdbNodeId = node.key().getNodeId();
1195 NodeId brNodeId = new NodeId(ovsdbNodeId.getValue()
1196 + "/" + ITMConstants.BRIDGE_URI_PREFIX + "/" + bridge);
1198 InstanceIdentifier<Node> bridgeIid =
1200 .create(NetworkTopology.class)
1201 .child(Topology.class, new TopologyKey(IfmConstants.OVSDB_TOPOLOGY_ID))
1202 .child(Node.class,new NodeKey(brNodeId));
1204 Optional<Node> opBridgeNode = ItmUtils.read(LogicalDatastoreType.OPERATIONAL, bridgeIid, dataBroker);
1206 if (opBridgeNode.isPresent()) {
1207 bridgeNode = opBridgeNode.get();
1209 if (bridgeNode != null) {
1210 ovsdbBridgeAugmentation = bridgeNode.augmentation(OvsdbBridgeAugmentation.class);
1213 if (ovsdbBridgeAugmentation != null && ovsdbBridgeAugmentation.getDatapathId() != null) {
1214 datapathId = ovsdbBridgeAugmentation.getDatapathId().getValue();
1220 * Gets the Network topology Node from Operational Datastore
1221 * based on Bridge Augmentation.
1223 * @param bridgeAugmentation bridge augmentation of OVSDB node
1225 * @param dataBroker data broker handle to perform operations on datastore
1227 * @return the Network Topology Node i.e. OVSDB node which is managing the specified bridge
1229 public static Node getOvsdbNode(OvsdbBridgeAugmentation bridgeAugmentation,
1230 DataBroker dataBroker) {
1231 Node ovsdbNode = null;
1232 Optional<Node> opOvsdbNode = Optional.absent();
1233 if (bridgeAugmentation != null) {
1234 InstanceIdentifier<Node> ovsdbNodeIid =
1235 (InstanceIdentifier<Node>) bridgeAugmentation.getManagedBy().getValue();
1236 opOvsdbNode = ItmUtils.read(LogicalDatastoreType.OPERATIONAL, ovsdbNodeIid, dataBroker);
1238 if (opOvsdbNode.isPresent()) {
1239 ovsdbNode = opOvsdbNode.get();
1245 * Gets the bridge datapath ID in string form from
1246 * Network topology Node's OvsdbBridgeAugmentation in the Operational DS.
1248 * @param augmentedNode Ovsdb Augmented Network Topology Node
1250 * @return the datapath ID of bridge in string form
1252 public static String getStrDatapathId(OvsdbBridgeAugmentation augmentedNode) {
1253 String datapathId = null;
1254 if (augmentedNode != null && augmentedNode.getDatapathId() != null) {
1255 datapathId = augmentedNode.getDatapathId().getValue();
1261 * Returns the dummy subnet (255.255.255.255/32) as IpPrefix object.
1263 * @return the dummy subnet (255.255.255.255/32) in IpPrefix object
1265 public static IpPrefix getDummySubnet() {
1266 return DUMMY_IP_PREFIX;
1270 * Deletes the transport zone from Configuration datastore.
1272 * @param tzName transport zone name
1273 * @param dataBroker data broker handle to perform operations on datastore
1275 public static void deleteTransportZoneFromConfigDS(String tzName, DataBroker dataBroker) {
1276 // check whether transport-zone exists in config DS.
1277 TransportZone transportZoneFromConfigDS = ItmUtils.getTransportZoneFromConfigDS(tzName, dataBroker);
1278 if (transportZoneFromConfigDS != null) {
1279 // it exists, delete default-TZ now
1280 InstanceIdentifier<TransportZone> path = InstanceIdentifier.builder(TransportZones.class)
1281 .child(TransportZone.class, new TransportZoneKey(tzName)).build();
1282 LOG.debug("Removing {} transport-zone from config DS.", tzName);
1284 SingleTransactionDataBroker.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, path);
1285 } catch (TransactionCommitFailedException e) {
1286 LOG.error("deleteTransportZoneFromConfigDS failed. {} could not be deleted.", tzName, e);
1292 * Validates the tunnelType argument and returnsTunnelTypeBase class object
1293 * corresponding to tunnelType obtained in String format.
1295 * @param tunnelType type of tunnel in string form
1297 * @return tunnel-type in TunnelTypeBase object
1299 public static Class<? extends TunnelTypeBase> getTunnelType(String tunnelType) {
1300 // validate tunnelType string, in case it is NULL or empty, then
1301 // take VXLAN tunnel type by default
1302 if (tunnelType == null || tunnelType.isEmpty()) {
1303 return TUNNEL_TYPE_MAP.get(ITMConstants.TUNNEL_TYPE_VXLAN);
1304 } else if (!tunnelType.equals(ITMConstants.TUNNEL_TYPE_VXLAN)
1305 && !tunnelType.equals(ITMConstants.TUNNEL_TYPE_GRE)) {
1306 // if tunnel type is some incorrect value, then
1307 // take VXLAN tunnel type by default
1308 return TUNNEL_TYPE_MAP.get(ITMConstants.TUNNEL_TYPE_VXLAN);
1311 // return TunnelTypeBase object corresponding to tunnel-type
1312 return TUNNEL_TYPE_MAP.get(tunnelType);
1315 public static List<TzMembership> removeTransportZoneMembership(TunnelEndPoints endPts, List<TzMembership> zones) {
1316 LOG.trace(" RemoveTransportZoneMembership TEPs {}, Membership to be removed {} ", endPts, zones);
1317 List<TzMembership> existingTzList = new ArrayList<>(endPts.getTzMembership()) ;
1318 for (TzMembership membership : zones) {
1319 existingTzList.remove(new TzMembershipBuilder().setZoneName(membership.getZoneName()).build());
1321 LOG.debug("Modified Membership List {}", existingTzList);
1322 return existingTzList;
1325 public static List<TzMembership> getOriginalTzMembership(TunnelEndPoints srcTep, BigInteger dpnId,
1326 Collection<DPNTEPsInfo> meshedDpnList) {
1327 LOG.trace("Original Membership for source DPN {}, source TEP {}", dpnId, srcTep);
1328 for (DPNTEPsInfo dstDpn : meshedDpnList) {
1329 if (dpnId.equals(dstDpn.getDPNID())) {
1330 List<TunnelEndPoints> endPts = dstDpn.getTunnelEndPoints();
1331 for (TunnelEndPoints tep : endPts) {
1332 if (tep.getIpAddress().equals(srcTep.getIpAddress())) {
1333 LOG.debug("Original Membership size {}", tep.getTzMembership().size()) ;
1334 return tep.getTzMembership();
1342 public static StateTunnelList buildStateTunnelList(StateTunnelListKey tlKey, String name, boolean state,
1343 TunnelOperStatus tunOpStatus, IInterfaceManager ifaceManager,
1344 DataBroker broker) {
1345 StateTunnelListBuilder stlBuilder = new StateTunnelListBuilder();
1346 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface =
1347 ItmUtils.getInterface(name, ifaceManager);
1348 IfTunnel ifTunnel = iface.augmentation(IfTunnel.class);
1349 ParentRefs parentRefs = iface.augmentation(ParentRefs.class);
1350 if (ifTunnel == null || parentRefs == null) {
1353 DstInfoBuilder dstInfoBuilder = new DstInfoBuilder();
1354 SrcInfoBuilder srcInfoBuilder = new SrcInfoBuilder();
1355 dstInfoBuilder.setTepIp(ifTunnel.getTunnelDestination());
1356 srcInfoBuilder.setTepIp(ifTunnel.getTunnelSource());
1357 // TODO: Add/Improve logic for device type
1358 InternalTunnel internalTunnel = ItmUtils.ITM_CACHE.getInternalTunnel(name);
1359 ExternalTunnel externalTunnel = ItmUtils.ITM_CACHE.getExternalTunnel(name);
1360 if (internalTunnel == null && externalTunnel == null) {
1361 // both not present in cache. let us update and try again.
1362 ItmUtils.updateTunnelsCache(broker);
1363 internalTunnel = ItmUtils.ITM_CACHE.getInternalTunnel(name);
1364 externalTunnel = ItmUtils.ITM_CACHE.getExternalTunnel(name);
1366 if (internalTunnel != null) {
1367 srcInfoBuilder.setTepDeviceId(internalTunnel.getSourceDPN().toString())
1368 .setTepDeviceType(TepTypeInternal.class);
1369 dstInfoBuilder.setTepDeviceId(internalTunnel.getDestinationDPN().toString())
1370 .setTepDeviceType(TepTypeInternal.class);
1371 stlBuilder.setTransportType(internalTunnel.getTransportType());
1372 } else if (externalTunnel != null) {
1373 ExternalTunnel tunnel = ItmUtils.ITM_CACHE.getExternalTunnel(name);
1374 srcInfoBuilder.setTepDeviceId(tunnel.getSourceDevice())
1375 .setTepDeviceType(getDeviceType(tunnel.getSourceDevice()));
1376 dstInfoBuilder.setTepDeviceId(tunnel.getDestinationDevice())
1377 .setTepDeviceType(getDeviceType(tunnel.getDestinationDevice()))
1378 .setTepIp(ifTunnel.getTunnelDestination());
1379 stlBuilder.setTransportType(tunnel.getTransportType());
1381 stlBuilder.withKey(tlKey).setTunnelInterfaceName(name).setOperState(tunOpStatus).setTunnelState(state)
1382 .setDstInfo(dstInfoBuilder.build()).setSrcInfo(srcInfoBuilder.build());
1383 return stlBuilder.build();
1386 private static Class<? extends TepTypeBase> getDeviceType(String device) {
1387 if (device.startsWith("hwvtep")) {
1388 return TepTypeHwvtep.class;
1389 } else if (device.contains("IpAddress")) {
1390 return TepTypeExternal.class;
1392 return TepTypeInternal.class;
1396 public static InstanceIdentifier<StateTunnelList> buildStateTunnelListId(StateTunnelListKey tlKey) {
1397 return InstanceIdentifier.builder(TunnelsState.class)
1398 .child(StateTunnelList.class, tlKey).build();
1402 public static Optional<InternalTunnel> getInternalTunnelFromDS(BigInteger srcDpn, BigInteger destDpn,
1403 Class<? extends TunnelTypeBase> type,
1404 DataBroker dataBroker) {
1405 InstanceIdentifier<InternalTunnel> pathLogicTunnel = InstanceIdentifier.create(TunnelList.class)
1406 .child(InternalTunnel.class,
1407 new InternalTunnelKey(destDpn, srcDpn, type));
1408 //TODO: need to be replaced by cached copy
1409 return ItmUtils.read(LogicalDatastoreType.CONFIGURATION, pathLogicTunnel, dataBroker);
1412 public static boolean isTunnelAggregationUsed(Class<? extends TunnelTypeBase> tunType) {
1413 return ItmTunnelAggregationHelper.isTunnelAggregationEnabled()
1414 && (tunType.isAssignableFrom(TunnelTypeVxlan.class)
1415 || tunType.isAssignableFrom(TunnelTypeLogicalGroup.class));
1418 public static List<TunnelOptions> buildTunnelOptions(TunnelEndPoints tep, ItmConfig itmConfig) {
1419 List<TunnelOptions> tunOptions = new ArrayList<>();
1421 String tos = tep.getOptionTunnelTos();
1423 tos = itmConfig.getDefaultTunnelTos();
1425 /* populate tos option only if its not default value of 0 */
1426 if (tos != null && !tos.equals("0")) {
1427 TunnelOptionsBuilder optionsBuilder = new TunnelOptionsBuilder();
1428 optionsBuilder.withKey(new TunnelOptionsKey("tos"));
1429 optionsBuilder.setTunnelOption("tos");
1430 optionsBuilder.setValue(tos);
1431 tunOptions.add(optionsBuilder.build());
1434 if (tep.getTunnelType() == TunnelTypeVxlan.class && itmConfig.isGpeExtensionEnabled()) {
1435 TunnelOptionsBuilder optionsBuilder = new TunnelOptionsBuilder();
1436 optionsBuilder.withKey(new TunnelOptionsKey("exts"));
1437 optionsBuilder.setTunnelOption("exts");
1438 optionsBuilder.setValue("gpe");
1439 tunOptions.add(optionsBuilder.build());
1441 return tunOptions.isEmpty() ? null : tunOptions;
1444 public static ExternalTunnel getExternalTunnelbyExternalTunnelKey(ExternalTunnelKey externalTunnelKey,
1445 InstanceIdentifier<ExternalTunnel> path,
1446 DataBroker dataBroker) {
1447 ExternalTunnel exTunnel = ITM_CACHE.getExternalTunnelKeyToExternalTunnels().get(externalTunnelKey);
1448 if (exTunnel == null) {
1449 Optional<ExternalTunnel> ext = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
1450 if (ext.isPresent()) {
1451 exTunnel = ext.get();
1457 public static List<DPNTEPsInfo> getDpnTEPsInfos(DataBroker dataBroker) {
1458 InstanceIdentifier<DpnEndpoints> iid = InstanceIdentifier.builder(DpnEndpoints.class).build();
1459 Optional<DpnEndpoints> dpnEndpoints = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, iid, dataBroker);
1460 if (dpnEndpoints.isPresent()) {
1461 return dpnEndpoints.get().getDPNTEPsInfo();
1463 return new ArrayList<>();
1467 public static InstanceIdentifier<TransportZone> getTZInstanceIdentifier(String tzName) {
1468 return InstanceIdentifier.builder(TransportZones.class).child(TransportZone.class,
1469 new TransportZoneKey(tzName)).build();
1473 * Returns the transport zone from Configuration datastore.
1475 * @param tzName transport zone name
1476 * @param dataBroker data broker handle to perform operations on datastore
1477 * @return the TransportZone object in Config DS
1479 // FIXME: Better is to implement cache to avoid datastore read.
1480 public static TransportZone getTransportZoneFromConfigDS(String tzName, DataBroker dataBroker) {
1481 InstanceIdentifier<TransportZone> tzonePath = getTZInstanceIdentifier(tzName);
1482 Optional<TransportZone> transportZoneOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, tzonePath,
1484 if (transportZoneOptional.isPresent()) {
1485 return transportZoneOptional.get();
1490 public static Class<? extends TunnelTypeBase> convertStringToTunnelType(String tunnelType) {
1491 Class<? extends TunnelTypeBase> tunType = TunnelTypeVxlan.class;
1492 if (STRING_CLASS_IMMUTABLE_BI_MAP.containsKey(tunnelType)) {
1493 tunType = STRING_CLASS_IMMUTABLE_BI_MAP.get(tunnelType);