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.rev170119.Tunnel;
59 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil;
60 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
61 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder;
62 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
63 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefixBuilder;
64 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType;
65 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
66 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
67 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
68 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
69 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlanBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnel;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnelBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefs;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefsBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelMonitoringTypeBase;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeGre;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeLogicalGroup;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeMplsOverGre;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.interfaces._interface.NodeIdentifier;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.interfaces._interface.NodeIdentifierBuilder;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.interfaces._interface.NodeIdentifierKey;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.tunnel.optional.params.TunnelOptions;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.tunnel.optional.params.TunnelOptionsBuilder;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.tunnel.optional.params.TunnelOptionsKey;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.ItmConfig;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.VtepConfigSchemas;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.VtepIpPools;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.VtepConfigSchema;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.VtepConfigSchemaBuilder;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.VtepConfigSchemaKey;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.vtep.config.schema.DpnIds;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.vtep.config.schema.DpnIdsBuilder;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.vtep.config.schema.DpnIdsKey;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.ip.pools.VtepIpPool;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.ip.pools.VtepIpPoolKey;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpointsBuilder;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.ExternalTunnelList;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeBase;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeExternal;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeHwvtep;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeInternal;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelList;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelOperStatus;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelsState;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoBuilder;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoKey;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPointsBuilder;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPointsKey;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.tunnel.end.points.TzMembership;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.tunnel.end.points.TzMembershipBuilder;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnel;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnelBuilder;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnelKey;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnel;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnelBuilder;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnelKey;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelList;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelListBuilder;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelListKey;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.state.tunnel.list.DstInfoBuilder;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.state.tunnel.list.SrcInfoBuilder;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.DcGatewayIpList;
129 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.NotHostedTransportZones;
130 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZones;
131 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.dc.gateway.ip.list.DcGatewayIp;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.not.hosted.transport.zones.TepsInNotHostedTransportZone;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.not.hosted.transport.zones.TepsInNotHostedTransportZoneKey;
134 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZone;
135 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZoneKey;
136 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.Subnets;
137 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.Vteps;
138 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
139 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
140 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
141 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
142 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
143 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
144 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
145 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
146 import org.opendaylight.yangtools.yang.binding.DataObject;
147 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
148 import org.slf4j.Logger;
149 import org.slf4j.LoggerFactory;
151 public final class ItmUtils {
153 private static final Logger LOG = LoggerFactory.getLogger(ItmUtils.class);
155 private static final String TUNNEL = "tun";
156 private static final IpPrefix DUMMY_IP_PREFIX = IpPrefixBuilder.getDefaultInstance(ITMConstants.DUMMY_PREFIX);
157 private static final long DEFAULT_MONITORING_INTERVAL = 100L;
158 public static final ItmCache ITM_CACHE = new ItmCache();
160 public static final ImmutableMap<String, Class<? extends TunnelTypeBase>>
162 new ImmutableMap.Builder<String, Class<? extends TunnelTypeBase>>()
163 .put(ITMConstants.TUNNEL_TYPE_GRE, TunnelTypeGre.class)
164 .put(ITMConstants.TUNNEL_TYPE_MPLSoGRE, TunnelTypeMplsOverGre.class)
165 .put(ITMConstants.TUNNEL_TYPE_VXLAN, TunnelTypeVxlan.class)
168 private static final BiMap<String,Class<? extends TunnelTypeBase>> STRING_CLASS_IMMUTABLE_BI_MAP =
169 ImmutableBiMap.copyOf(TUNNEL_TYPE_MAP);
174 public static final FutureCallback<Void> DEFAULT_CALLBACK = new FutureCallback<Void>() {
176 public void onSuccess(Void result) {
177 LOG.debug("Success in Datastore write operation");
181 public void onFailure(@Nonnull Throwable error) {
182 LOG.error("Error in Datastore write operation", error);
187 * Synchronous blocking read from data store.
190 * {@link SingleTransactionDataBroker#syncReadOptional(DataBroker, LogicalDatastoreType, InstanceIdentifier)}
194 @SuppressWarnings("checkstyle:IllegalCatch")
195 public static <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType,
196 InstanceIdentifier<T> path, DataBroker broker) {
197 try (ReadOnlyTransaction tx = broker.newReadOnlyTransaction()) {
198 return tx.read(datastoreType, path).get();
199 } catch (Exception e) {
200 throw new RuntimeException(e);
206 * Asynchronous non-blocking write to data store.
208 * @deprecated Use {@link ManagedNewTransactionRunner} instead of this.
211 public static <T extends DataObject> void asyncWrite(LogicalDatastoreType datastoreType,
212 InstanceIdentifier<T> path, T data, DataBroker broker,
213 FutureCallback<Void> callback) {
214 WriteTransaction tx = broker.newWriteOnlyTransaction();
215 tx.put(datastoreType, path, data, true);
216 Futures.addCallback(tx.submit(), callback);
220 * Asynchronous non-blocking update to data store.
222 * @deprecated Use {@link ManagedNewTransactionRunner} instead of this.
225 public static <T extends DataObject> void asyncUpdate(LogicalDatastoreType datastoreType,
226 InstanceIdentifier<T> path, T data, DataBroker broker,
227 FutureCallback<Void> callback) {
228 WriteTransaction tx = broker.newWriteOnlyTransaction();
229 tx.merge(datastoreType, path, data, true);
230 Futures.addCallback(tx.submit(), callback);
234 * Asynchronous non-blocking single delete to data store.
236 * @deprecated Use {@link ManagedNewTransactionRunner} instead of this.
239 public static <T extends DataObject> void asyncDelete(LogicalDatastoreType datastoreType,
240 InstanceIdentifier<T> path, DataBroker broker,
241 FutureCallback<Void> callback) {
242 WriteTransaction tx = broker.newWriteOnlyTransaction();
243 tx.delete(datastoreType, path);
244 Futures.addCallback(tx.submit(), callback);
248 * Asynchronous non-blocking bulk delete to data store.
250 * @deprecated Use {@link ManagedNewTransactionRunner} instead of this.
253 public static <T extends DataObject> void asyncBulkRemove(final DataBroker broker,
254 final LogicalDatastoreType datastoreType,
255 List<InstanceIdentifier<T>> pathList,
256 FutureCallback<Void> callback) {
257 if (!pathList.isEmpty()) {
258 WriteTransaction tx = broker.newWriteOnlyTransaction();
259 for (InstanceIdentifier<T> path : pathList) {
260 tx.delete(datastoreType, path);
262 Futures.addCallback(tx.submit(), callback);
266 public static String getInterfaceName(final BigInteger datapathid, final String portName, final Integer vlanId) {
267 return String.format("%s:%s:%s", datapathid, portName, vlanId);
270 public static BigInteger getDpnIdFromInterfaceName(String interfaceName) {
271 String[] dpnStr = interfaceName.split(":");
272 return new BigInteger(dpnStr[0]);
275 public static String getTrunkInterfaceName(String parentInterfaceName,
276 String localHostName, String remoteHostName, String tunnelType) {
277 String tunnelTypeStr;
278 if (tunnelType.contains("TunnelTypeGre")) {
279 tunnelTypeStr = ITMConstants.TUNNEL_TYPE_GRE;
280 } else if (tunnelType.contains("TunnelTypeLogicalGroup")) {
281 tunnelTypeStr = ITMConstants.TUNNEL_TYPE_LOGICAL_GROUP_VXLAN;
283 tunnelTypeStr = ITMConstants.TUNNEL_TYPE_VXLAN;
285 String trunkInterfaceName = String.format("%s:%s:%s:%s", parentInterfaceName, localHostName,
286 remoteHostName, tunnelTypeStr);
287 LOG.trace("trunk interface name is {}", trunkInterfaceName);
288 trunkInterfaceName = String.format("%s%s", TUNNEL, getUniqueIdString(trunkInterfaceName));
289 return trunkInterfaceName;
292 public static void releaseIdForTrunkInterfaceName(String parentInterfaceName,
293 String localHostName, String remoteHostName, String tunnelType) {
294 String tunnelTypeStr;
295 if (tunnelType.contains("TunnelTypeGre")) {
296 tunnelTypeStr = ITMConstants.TUNNEL_TYPE_GRE;
298 tunnelTypeStr = ITMConstants.TUNNEL_TYPE_VXLAN;
300 String trunkInterfaceName = String.format("%s:%s:%s:%s", parentInterfaceName, localHostName,
301 remoteHostName, tunnelTypeStr);
302 LOG.trace("Releasing Id for trunkInterface - {}", trunkInterfaceName);
305 public static String getLogicalTunnelGroupName(BigInteger srcDpnId, BigInteger destDpnId) {
306 String tunnelTypeStr = ITMConstants.TUNNEL_TYPE_LOGICAL_GROUP_VXLAN;
307 String groupName = String.format("%s:%s:%s", srcDpnId.toString(), destDpnId.toString(), tunnelTypeStr);
308 LOG.trace("logical tunnel group name is {}", groupName);
309 groupName = String.format("%s%s", TUNNEL, getUniqueIdString(groupName));
313 public static InetAddress getInetAddressFromIpAddress(IpAddress ip) {
314 return IetfInetUtil.INSTANCE.inetAddressFor(ip);
317 public static InstanceIdentifier<DPNTEPsInfo> getDpnTepInstance(BigInteger dpIdKey) {
318 return InstanceIdentifier.builder(DpnEndpoints.class).child(DPNTEPsInfo.class, new DPNTEPsInfoKey(dpIdKey))
322 public static DPNTEPsInfo createDPNTepInfo(BigInteger dpId, List<TunnelEndPoints> endpoints) {
323 return new DPNTEPsInfoBuilder().withKey(new DPNTEPsInfoKey(dpId)).setTunnelEndPoints(endpoints).build();
326 public static TunnelEndPoints createTunnelEndPoints(BigInteger dpnId, IpAddress ipAddress, String portName,
327 boolean isOfTunnel, int vlanId, IpPrefix prefix,
328 IpAddress gwAddress, List<TzMembership> zones,
329 Class<? extends TunnelTypeBase> tunnelType,
331 // when Interface Mgr provides support to take in Dpn Id
332 return new TunnelEndPointsBuilder().withKey(new TunnelEndPointsKey(ipAddress, portName,tunnelType, vlanId))
333 .setSubnetMask(prefix).setGwIpAddress(gwAddress).setTzMembership(zones)
334 .setOptionOfTunnel(isOfTunnel).setInterfaceName(ItmUtils.getInterfaceName(dpnId, portName, vlanId))
335 .setTunnelType(tunnelType)
336 .setOptionTunnelTos(tos)
340 public static DpnEndpoints createDpnEndpoints(List<DPNTEPsInfo> dpnTepInfo) {
341 return new DpnEndpointsBuilder().setDPNTEPsInfo(dpnTepInfo).build();
344 public static InstanceIdentifier<Interface> buildId(String interfaceName) {
345 return InstanceIdentifier.builder(Interfaces.class).child(Interface.class, new InterfaceKey(interfaceName))
349 public static InstanceIdentifier<IfTunnel> buildTunnelId(String ifName) {
350 return InstanceIdentifier.builder(Interfaces.class)
351 .child(Interface.class, new InterfaceKey(ifName)).augmentation(IfTunnel.class).build();
354 public static Interface buildLogicalTunnelInterface(BigInteger dpn, String ifName, String desc, boolean enabled) {
355 InterfaceBuilder builder = new InterfaceBuilder().withKey(new InterfaceKey(ifName)).setName(ifName)
356 .setDescription(desc).setEnabled(enabled).setType(Tunnel.class);
357 ParentRefs parentRefs = new ParentRefsBuilder().setDatapathNodeIdentifier(dpn).build();
358 builder.addAugmentation(ParentRefs.class, parentRefs);
360 IfTunnel tunnel = new IfTunnelBuilder()
361 .setTunnelDestination(IpAddressBuilder.getDefaultInstance(ITMConstants.DUMMY_IP_ADDRESS))
362 .setTunnelSource(IpAddressBuilder.getDefaultInstance(ITMConstants.DUMMY_IP_ADDRESS)).setInternal(true)
363 .setMonitorEnabled(false).setTunnelInterfaceType(TunnelTypeLogicalGroup.class)
364 .setTunnelRemoteIpFlow(false).build();
365 builder.addAugmentation(IfTunnel.class, tunnel);
366 return builder.build();
369 public static Interface buildTunnelInterface(BigInteger dpn, String ifName, String desc, boolean enabled,
370 Class<? extends TunnelTypeBase> tunType, IpAddress localIp,
371 IpAddress remoteIp, IpAddress gatewayIp, Integer vlanId,
372 boolean internal, Boolean monitorEnabled,
373 Class<? extends TunnelMonitoringTypeBase> monitorProtocol,
374 Integer monitorInterval, boolean useOfTunnel,
375 List<TunnelOptions> tunOptions) {
377 return buildTunnelInterface(dpn, ifName, desc, enabled, tunType, localIp, remoteIp, gatewayIp, vlanId,
378 internal, monitorEnabled, monitorProtocol, monitorInterval, useOfTunnel, null,
382 public static Interface buildTunnelInterface(BigInteger dpn, String ifName, String desc, boolean enabled,
383 Class<? extends TunnelTypeBase> tunType, IpAddress localIp,
384 IpAddress remoteIp, IpAddress gatewayIp, Integer vlanId,
385 boolean internal, Boolean monitorEnabled,
386 Class<? extends TunnelMonitoringTypeBase> monitorProtocol,
387 Integer monitorInterval, boolean useOfTunnel, String parentIfaceName,
388 List<TunnelOptions> tunnelOptions) {
389 InterfaceBuilder builder = new InterfaceBuilder().withKey(new InterfaceKey(ifName)).setName(ifName)
390 .setDescription(desc).setEnabled(enabled).setType(Tunnel.class);
391 ParentRefs parentRefs =
392 new ParentRefsBuilder().setDatapathNodeIdentifier(dpn).setParentInterface(parentIfaceName).build();
393 builder.addAugmentation(ParentRefs.class, parentRefs);
394 Long monitoringInterval = null;
396 IfL2vlan l2vlan = new IfL2vlanBuilder().setVlanId(new VlanId(vlanId)).build();
397 builder.addAugmentation(IfL2vlan.class, l2vlan);
399 LOG.debug("buildTunnelInterface: monitorProtocol = {} and monitorInterval = {}",
400 monitorProtocol.getName(),monitorInterval);
402 if (monitorInterval != null) {
403 monitoringInterval = monitorInterval.longValue();
406 IfTunnel tunnel = new IfTunnelBuilder().setTunnelDestination(remoteIp).setTunnelGateway(gatewayIp)
407 .setTunnelSource(localIp).setTunnelInterfaceType(tunType).setInternal(internal)
408 .setMonitorEnabled(monitorEnabled).setMonitorProtocol(monitorProtocol)
409 .setMonitorInterval(monitoringInterval).setTunnelRemoteIpFlow(useOfTunnel)
410 .setTunnelOptions(tunnelOptions)
412 builder.addAugmentation(IfTunnel.class, tunnel);
413 return builder.build();
416 public static Interface buildHwTunnelInterface(String tunnelIfName, String desc, boolean enabled, String topoId,
417 String nodeId, Class<? extends TunnelTypeBase> tunType,
418 IpAddress srcIp, IpAddress destIp, IpAddress gwIp,
419 Boolean monitorEnabled,
420 Class<? extends TunnelMonitoringTypeBase> monitorProtocol,
421 Integer monitorInterval) {
422 InterfaceBuilder builder = new InterfaceBuilder().withKey(new InterfaceKey(tunnelIfName))
423 .setName(tunnelIfName).setDescription(desc).setEnabled(enabled).setType(Tunnel.class);
424 List<NodeIdentifier> nodeIds = new ArrayList<>();
425 NodeIdentifier hwNode = new NodeIdentifierBuilder().withKey(new NodeIdentifierKey(topoId))
426 .setTopologyId(topoId).setNodeId(nodeId).build();
428 ParentRefs parent = new ParentRefsBuilder().setNodeIdentifier(nodeIds).build();
429 builder.addAugmentation(ParentRefs.class, parent);
430 IfTunnel tunnel = new IfTunnelBuilder().setTunnelDestination(destIp).setTunnelGateway(gwIp)
431 .setTunnelSource(srcIp).setMonitorEnabled(monitorEnabled == null || monitorEnabled)
432 .setMonitorProtocol(monitorProtocol == null ? ITMConstants.DEFAULT_MONITOR_PROTOCOL : monitorProtocol)
433 .setMonitorInterval(DEFAULT_MONITORING_INTERVAL).setTunnelInterfaceType(tunType).setInternal(false)
435 builder.addAugmentation(IfTunnel.class, tunnel);
436 LOG.trace("iftunnel {} built from hwvtep {} ", tunnel, nodeId);
437 return builder.build();
440 public static InternalTunnel buildInternalTunnel(BigInteger srcDpnId, BigInteger dstDpnId,
441 Class<? extends TunnelTypeBase> tunType,
442 String trunkInterfaceName) {
443 return new InternalTunnelBuilder().withKey(new InternalTunnelKey(dstDpnId, srcDpnId, tunType))
444 .setDestinationDPN(dstDpnId)
445 .setSourceDPN(srcDpnId).setTransportType(tunType)
446 .setTunnelInterfaceNames(Collections.singletonList(trunkInterfaceName)).build();
449 public static ExternalTunnel buildExternalTunnel(String srcNode, String dstNode,
450 Class<? extends TunnelTypeBase> tunType,
451 String trunkInterfaceName) {
452 return new ExternalTunnelBuilder().withKey(
453 new ExternalTunnelKey(dstNode, srcNode, tunType))
454 .setSourceDevice(srcNode).setDestinationDevice(dstNode)
455 .setTunnelInterfaceName(trunkInterfaceName)
456 .setTransportType(tunType).build();
459 private static String getUniqueIdString(String idKey) {
460 return UUID.nameUUIDFromBytes(idKey.getBytes(StandardCharsets.UTF_8)).toString().substring(0, 12)
464 public static List<DPNTEPsInfo> getDpnTepListFromDpnId(DPNTEPsInfoCache dpnTEPsInfoCache, List<BigInteger> dpnIds) {
465 Collection<DPNTEPsInfo> meshedDpnList = dpnTEPsInfoCache.getAllPresent();
466 List<DPNTEPsInfo> cfgDpnList = new ArrayList<>();
467 for (BigInteger dpnId : dpnIds) {
468 for (DPNTEPsInfo teps : meshedDpnList) {
469 if (dpnId.equals(teps.getDPNID())) {
470 cfgDpnList.add(teps);
478 @SuppressWarnings("checkstyle:IllegalCatch")
479 public static void addTerminatingServiceTable(TypedReadWriteTransaction<Configuration> tx,
480 BigInteger dpnId, IMdsalApiManager mdsalManager) {
481 LOG.trace("Installing PUNT to Controller flow in DPN {} ", dpnId);
482 List<ActionInfo> listActionInfo = new ArrayList<>();
483 listActionInfo.add(new ActionPuntToController());
486 List<MatchInfo> mkMatches = new ArrayList<>();
488 mkMatches.add(new MatchTunnelId(BigInteger.valueOf(ITMConstants.LLDP_SERVICE_ID)));
490 List<InstructionInfo> mkInstructions = new ArrayList<>();
491 mkInstructions.add(new InstructionApplyActions(listActionInfo));
493 FlowEntity terminatingServiceTableFlowEntity = MDSALUtil
494 .buildFlowEntity(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE,
495 getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE, ITMConstants.LLDP_SERVICE_ID),
496 5, String.format("%s:%d","ITM Flow Entry ", ITMConstants.LLDP_SERVICE_ID), 0, 0,
497 ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(ITMConstants.LLDP_SERVICE_ID)),
498 mkMatches, mkInstructions);
499 mdsalManager.addFlow(tx, terminatingServiceTableFlowEntity);
500 } catch (Exception e) {
501 LOG.error("Error while setting up Table 36 for {}", dpnId, e);
505 @SuppressWarnings("checkstyle:IllegalCatch")
506 public static void removeTerminatingServiceTable(TypedReadWriteTransaction<Configuration> tx,
507 BigInteger dpnId, IMdsalApiManager mdsalManager) {
508 LOG.trace("Removing PUNT to Controller flow in DPN {} ", dpnId);
511 mdsalManager.removeFlow(tx, dpnId,
512 getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE, ITMConstants.LLDP_SERVICE_ID),
513 NwConstants.INTERNAL_TUNNEL_TABLE);
514 } catch (Exception e) {
515 LOG.error("Error while setting up Table 36 for {}", dpnId, e);
519 private static String getFlowRef(long termSvcTable, int svcId) {
520 return String.valueOf(termSvcTable) + svcId;
523 public static InstanceIdentifier<VtepConfigSchema> getVtepConfigSchemaIdentifier(String schemaName) {
524 return InstanceIdentifier.builder(VtepConfigSchemas.class)
525 .child(VtepConfigSchema.class, new VtepConfigSchemaKey(schemaName)).build();
528 public static InstanceIdentifier<VtepConfigSchema> getVtepConfigSchemaIdentifier() {
529 return InstanceIdentifier.builder(VtepConfigSchemas.class).child(VtepConfigSchema.class).build();
532 public static InstanceIdentifier<VtepConfigSchemas> getVtepConfigSchemasIdentifier() {
533 return InstanceIdentifier.builder(VtepConfigSchemas.class).build();
536 public static InstanceIdentifier<VtepIpPool> getVtepIpPoolIdentifier(String subnetCidr) {
537 return InstanceIdentifier.builder(VtepIpPools.class).child(VtepIpPool.class, new VtepIpPoolKey(subnetCidr))
541 public static VtepConfigSchema validateForAddVtepConfigSchema(VtepConfigSchema schema,
542 List<VtepConfigSchema> existingSchemas) {
543 VtepConfigSchema validSchema = validateVtepConfigSchema(schema);
544 for (VtepConfigSchema existingSchema : emptyIfNull(existingSchemas)) {
545 if (!StringUtils.equalsIgnoreCase(schema.getSchemaName(), existingSchema.getSchemaName())
546 && schema.getSubnet().equals(existingSchema.getSubnet())) {
547 String subnetCidr = getSubnetCidrAsString(schema.getSubnet());
548 Preconditions.checkArgument(false, "VTEP schema with subnet [" + subnetCidr
549 + "] already exists. Multiple VTEP schemas with same subnet is not allowed.");
552 if (isNotEmpty(getDpnIdList(validSchema.getDpnIds()))) {
553 String tzone = validSchema.getTransportZoneName();
554 List<BigInteger> lstDpns = getConflictingDpnsAlreadyConfiguredWithTz(validSchema.getSchemaName(), tzone,
555 getDpnIdList(validSchema.getDpnIds()), existingSchemas);
556 if (!lstDpns.isEmpty()) {
557 Preconditions.checkArgument(false, "DPN's " + lstDpns + " already configured for transport zone "
558 + tzone + ". Only one end point per transport Zone per Dpn is allowed.");
560 if (schema.getTunnelType().equals(TunnelTypeGre.class)) {
561 validateForSingleGreTep(validSchema.getSchemaName(), getDpnIdList(validSchema.getDpnIds()),
568 private static void validateForSingleGreTep(String schemaName, List<BigInteger> lstDpnsForAdd,
569 List<VtepConfigSchema> existingSchemas) {
570 for (VtepConfigSchema existingSchema : emptyIfNull(existingSchemas)) {
571 if (TunnelTypeGre.class.equals(existingSchema.getTunnelType())
572 && !StringUtils.equalsIgnoreCase(schemaName, existingSchema.getSchemaName())) {
573 List<BigInteger> lstConflictingDpns = new ArrayList<>(getDpnIdList(existingSchema.getDpnIds()));
574 lstConflictingDpns.retainAll(emptyIfNull(lstDpnsForAdd));
575 if (!lstConflictingDpns.isEmpty()) {
576 String errMsg = "DPN's " + lstConflictingDpns
577 + " already configured with GRE TEP. Mutiple GRE TEP's on a single DPN are not allowed.";
578 Preconditions.checkArgument(false, errMsg);
584 public static VtepConfigSchema validateVtepConfigSchema(VtepConfigSchema schema) {
585 Preconditions.checkNotNull(schema);
586 Preconditions.checkArgument(StringUtils.isNotBlank(schema.getSchemaName()));
587 Preconditions.checkArgument(StringUtils.isNotBlank(schema.getPortName()));
588 Preconditions.checkArgument(schema.getVlanId() >= 0 && schema.getVlanId() < 4095,
589 "Invalid VLAN ID, range (0-4094)");
590 Preconditions.checkArgument(StringUtils.isNotBlank(schema.getTransportZoneName()));
591 Preconditions.checkNotNull(schema.getSubnet());
592 String subnetCidr = getSubnetCidrAsString(schema.getSubnet());
593 SubnetUtils subnetUtils = new SubnetUtils(subnetCidr);
594 IpAddress gatewayIp = schema.getGatewayIp();
595 if (gatewayIp != null) {
596 String strGatewayIp = gatewayIp.stringValue();
597 if (!strGatewayIp.equals(ITMConstants.DUMMY_IP_ADDRESS) && !subnetUtils.getInfo().isInRange(strGatewayIp)) {
598 Preconditions.checkArgument(false, "Gateway IP address " + strGatewayIp
599 + " is not in subnet range " + subnetCidr);
602 ItmUtils.getExcludeIpAddresses(schema.getExcludeIpFilter(), subnetUtils.getInfo());
603 return new VtepConfigSchemaBuilder(schema).setTunnelType(schema.getTunnelType()).build();
606 public static String validateTunnelType(String tunnelType) {
607 if (tunnelType == null) {
608 tunnelType = ITMConstants.TUNNEL_TYPE_VXLAN;
610 tunnelType = StringUtils.upperCase(tunnelType);
611 String error = "Invalid tunnel type. Valid values: "
612 + ITMConstants.TUNNEL_TYPE_VXLAN + " | " + ITMConstants.TUNNEL_TYPE_GRE;
613 Preconditions.checkArgument(ITMConstants.TUNNEL_TYPE_VXLAN.equals(tunnelType)
614 || ITMConstants.TUNNEL_TYPE_GRE.equals(tunnelType), error);
619 private static List<BigInteger> getConflictingDpnsAlreadyConfiguredWithTz(String schemaName, String tzone,
620 List<BigInteger> lstDpns,
621 List<VtepConfigSchema> existingSchemas) {
622 List<BigInteger> lstConflictingDpns = new ArrayList<>();
623 for (VtepConfigSchema schema : emptyIfNull(existingSchemas)) {
624 if (!StringUtils.equalsIgnoreCase(schemaName, schema.getSchemaName())
625 && StringUtils.equals(schema.getTransportZoneName(), tzone)) {
626 lstConflictingDpns = new ArrayList<>(getDpnIdList(schema.getDpnIds()));
627 lstConflictingDpns.retainAll(lstDpns);
628 if (!lstConflictingDpns.isEmpty()) {
633 return lstConflictingDpns;
636 public static VtepConfigSchema constructVtepConfigSchema(String schemaName, String portName, Integer vlanId,
637 String subnetMask, String gatewayIp, String transportZone,
638 String tunnelType, List<BigInteger> dpnIds,
639 String excludeIpFilter) {
640 IpAddress gatewayIpObj = StringUtils.isBlank(gatewayIp) ? null : IpAddressBuilder.getDefaultInstance(gatewayIp);
641 IpPrefix subnet = StringUtils.isBlank(subnetMask) ? null : IpPrefixBuilder.getDefaultInstance(subnetMask);
642 Class<? extends TunnelTypeBase> tunType ;
643 if (tunnelType.equals(ITMConstants.TUNNEL_TYPE_VXLAN)) {
644 tunType = TunnelTypeVxlan.class ;
646 tunType = TunnelTypeGre.class ;
648 VtepConfigSchemaBuilder schemaBuilder = new VtepConfigSchemaBuilder().setSchemaName(schemaName)
649 .setPortName(portName).setVlanId(vlanId).setSubnet(subnet).setGatewayIp(gatewayIpObj)
650 .setTransportZoneName(transportZone).setTunnelType(tunType).setDpnIds(getDpnIdsListFromBigInt(dpnIds))
651 .setExcludeIpFilter(excludeIpFilter);
652 return schemaBuilder.build();
655 public static List<IpAddress> getExcludeIpAddresses(String excludeIpFilter, SubnetInfo subnetInfo) {
656 final List<IpAddress> lstIpAddress = new ArrayList<>();
657 if (StringUtils.isBlank(excludeIpFilter)) {
660 final String[] arrIps = StringUtils.split(excludeIpFilter, ',');
661 for (String ip : arrIps) {
662 if (StringUtils.countMatches(ip, "-") == 1) {
663 final String[] arrIpRange = StringUtils.split(ip, '-');
664 String strStartIp = StringUtils.trim(arrIpRange[0]);
665 String strEndIp = StringUtils.trim(arrIpRange[1]);
666 Preconditions.checkArgument(InetAddresses.isInetAddress(strStartIp),
667 "Invalid exclude IP filter: invalid IP address value " + strStartIp);
668 Preconditions.checkArgument(InetAddresses.isInetAddress(strEndIp),
669 "Invalid exclude IP filter: invalid IP address value " + strEndIp);
670 Preconditions.checkArgument(subnetInfo.isInRange(strStartIp),
671 "Invalid exclude IP filter: IP address [" + strStartIp
672 + "] not in subnet range " + subnetInfo.getCidrSignature());
673 Preconditions.checkArgument(subnetInfo.isInRange(strEndIp),
674 "Invalid exclude IP filter: IP address [" + strEndIp
675 + "] not in subnet range " + subnetInfo.getCidrSignature());
676 int startIp = subnetInfo.asInteger(strStartIp);
677 int endIp = subnetInfo.asInteger(strEndIp);
679 Preconditions.checkArgument(startIp < endIp,
680 "Invalid exclude IP filter: Invalid range [" + ip + "] ");
681 for (int iter = startIp; iter <= endIp; iter++) {
682 String ipAddress = ipFormat(toIpArray(iter));
683 validateAndAddIpAddressToList(subnetInfo, lstIpAddress, ipAddress);
686 validateAndAddIpAddressToList(subnetInfo, lstIpAddress, ip);
692 private static void validateAndAddIpAddressToList(SubnetInfo subnetInfo, final List<IpAddress> lstIpAddress,
694 String ip = StringUtils.trim(ipAddress);
695 Preconditions.checkArgument(InetAddresses.isInetAddress(ip),
696 "Invalid exclude IP filter: invalid IP address value " + ip);
697 Preconditions.checkArgument(subnetInfo.isInRange(ip),
698 "Invalid exclude IP filter: IP address [" + ip + "] not in subnet range "
699 + subnetInfo.getCidrSignature());
700 lstIpAddress.add(IpAddressBuilder.getDefaultInstance(ip));
703 private static int[] toIpArray(int val) {
704 int[] ret = new int[4];
705 for (int iter = 3; iter >= 0; --iter) {
706 ret[iter] |= val >>> 8 * (3 - iter) & 0xff;
711 private static String ipFormat(int[] octets) {
712 StringBuilder str = new StringBuilder();
713 for (int iter = 0; iter < octets.length; ++iter) {
714 str.append(octets[iter]);
715 if (iter != octets.length - 1) {
719 return str.toString();
722 public static VtepConfigSchema validateForUpdateVtepSchema(String schemaName, List<BigInteger> lstDpnsForAdd,
723 List<BigInteger> lstDpnsForDelete,
724 IITMProvider itmProvider) {
725 Preconditions.checkArgument(StringUtils.isNotBlank(schemaName));
726 if ((lstDpnsForAdd == null || lstDpnsForAdd.isEmpty())
727 && (lstDpnsForDelete == null || lstDpnsForDelete.isEmpty())) {
728 Preconditions.checkArgument(false,
729 "DPN ID list for add | delete is null or empty in schema " + schemaName);
731 VtepConfigSchema schema = itmProvider.getVtepConfigSchema(schemaName);
732 if (schema == null) {
733 Preconditions.checkArgument(false, "Specified VTEP Schema [" + schemaName
734 + "] doesn't exists!");
736 List<BigInteger> existingDpnIds = getDpnIdList(schema.getDpnIds());
737 if (isNotEmpty(lstDpnsForAdd)) {
738 List<BigInteger> lstAlreadyExistingDpns = new ArrayList<>(existingDpnIds);
739 lstAlreadyExistingDpns.retainAll(lstDpnsForAdd);
740 Preconditions.checkArgument(lstAlreadyExistingDpns.isEmpty(),
741 "DPN ID's " + lstAlreadyExistingDpns
742 + " already exists in VTEP schema [" + schemaName + "]");
743 if (schema.getTunnelType().equals(TunnelTypeGre.class)) {
744 validateForSingleGreTep(schema.getSchemaName(), lstDpnsForAdd, itmProvider.getAllVtepConfigSchemas());
747 if (isNotEmpty(lstDpnsForDelete)) {
748 if (existingDpnIds.isEmpty()) {
749 String builder = "DPN ID's " + lstDpnsForDelete
750 + " specified for delete from VTEP schema [" + schemaName
751 + "] are not configured in the schema.";
752 Preconditions.checkArgument(false, builder);
753 } else if (!existingDpnIds.containsAll(lstDpnsForDelete)) {
754 List<BigInteger> lstConflictingDpns = new ArrayList<>(lstDpnsForDelete);
755 lstConflictingDpns.removeAll(existingDpnIds);
756 String builder = "DPN ID's " + lstConflictingDpns
757 + " specified for delete from VTEP schema [" + schemaName
758 + "] are not configured in the schema.";
759 Preconditions.checkArgument(false, builder);
765 public static String getSubnetCidrAsString(IpPrefix subnet) {
766 return subnet == null ? StringUtils.EMPTY : subnet.stringValue();
769 public static <T> List<T> emptyIfNull(List<T> list) {
770 return list == null ? Collections.emptyList() : list;
773 public static <T> boolean isEmpty(Collection<T> collection) {
774 return collection == null || collection.isEmpty();
777 public static <T> boolean isNotEmpty(Collection<T> collection) {
778 return !isEmpty(collection);
782 public static HwVtep createHwVtepObject(String topoId, String nodeId, IpAddress ipAddress, IpPrefix ipPrefix,
783 IpAddress gatewayIP, int vlanID,
784 Class<? extends TunnelTypeBase> tunneltype, TransportZone transportZone) {
785 HwVtep hwVtep = new HwVtep();
786 hwVtep.setGatewayIP(gatewayIP);
787 hwVtep.setHwIp(ipAddress);
788 hwVtep.setIpPrefix(ipPrefix);
789 hwVtep.setNodeId(nodeId);
790 hwVtep.setTopoId(topoId);
791 hwVtep.setTransportZone(transportZone.getZoneName());
792 hwVtep.setTunnelType(tunneltype);
793 hwVtep.setVlanID(vlanID);
797 public static String getHwParentIf(String topoId, String srcNodeid) {
798 return String.format("%s:%s", topoId, srcNodeid);
802 * Synchronous blocking write to data store.
805 * {@link SingleTransactionDataBroker#syncWrite(DataBroker, LogicalDatastoreType, InstanceIdentifier, DataObject)}
809 public static <T extends DataObject> void syncWrite(LogicalDatastoreType datastoreType,
810 InstanceIdentifier<T> path, T data, DataBroker broker) {
811 WriteTransaction tx = broker.newWriteOnlyTransaction();
812 tx.put(datastoreType, path, data, true);
815 } catch (InterruptedException | ExecutionException e) {
816 LOG.error("ITMUtils:SyncWrite , Error writing to datastore (path, data) : ({}, {})", path, data);
817 throw new RuntimeException(e.getMessage(), e);
822 public static List<BigInteger> getDpnIdList(List<DpnIds> dpnIds) {
823 List<BigInteger> dpnList = new ArrayList<>() ;
824 for (DpnIds dpn : dpnIds) {
825 dpnList.add(dpn.getDPN()) ;
830 public static List<DpnIds> getDpnIdsListFromBigInt(List<BigInteger> dpnIds) {
831 List<DpnIds> dpnIdList = new ArrayList<>();
832 DpnIdsBuilder builder = new DpnIdsBuilder();
833 for (BigInteger dpnId : dpnIds) {
834 dpnIdList.add(builder.withKey(new DpnIdsKey(dpnId)).setDPN(dpnId).build());
839 public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces
840 .rev140508.interfaces.state.Interface> buildStateInterfaceId(
841 String interfaceName) {
842 return InstanceIdentifier.builder(InterfacesState.class)
843 .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
844 .state.Interface.class,
845 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces
846 .rev140508.interfaces.state.InterfaceKey(
847 interfaceName)).build();
851 public static List<String> getInternalTunnelInterfaces(DataBroker dataBroker) {
852 List<String> tunnelList = new ArrayList<>();
853 Collection<String> internalInterfaces = ITM_CACHE.getAllInternalInterfaces();
854 if (internalInterfaces.isEmpty()) {
855 updateTunnelsCache(dataBroker);
856 internalInterfaces = ITM_CACHE.getAllInternalInterfaces();
858 LOG.debug("ItmUtils.getTunnelList Cache Internal Interfaces size: {} ", internalInterfaces.size());
859 tunnelList.addAll(internalInterfaces);
860 LOG.trace("ItmUtils.getTunnelList Internal: {}", tunnelList);
864 public static List<InternalTunnel> getInternalTunnelsFromCache(DataBroker dataBroker) {
865 List<InternalTunnel> tunnelList = new ArrayList<>();
866 Collection<InternalTunnel> internalInterfaces = ITM_CACHE.getAllInternalTunnel();
867 if (internalInterfaces.isEmpty()) {
868 updateTunnelsCache(dataBroker);
869 internalInterfaces = ITM_CACHE.getAllInternalTunnel();
871 LOG.debug("Number of Internal Tunnel Interfaces in cache: {} ", internalInterfaces.size());
872 tunnelList.addAll(internalInterfaces);
873 LOG.trace("List of Internal Tunnels: {}", tunnelList);
877 public static List<String> getTunnelsofTzone(List<HwVtep> hwVteps, String tzone, DataBroker dataBroker,
878 Boolean hwVtepsExist) {
879 List<String> tunnels = new ArrayList<>();
880 InstanceIdentifier<TransportZone> path = InstanceIdentifier.builder(TransportZones.class)
881 .child(TransportZone.class, new TransportZoneKey(tzone)).build();
882 Optional<TransportZone> transportZoneOptional =
883 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
884 if (transportZoneOptional.isPresent()) {
885 TransportZone transportZone = transportZoneOptional.get();
886 Class<? extends TunnelTypeBase> tunType = transportZone.getTunnelType();
887 if (transportZone.getSubnets() != null && !transportZone.getSubnets().isEmpty()) {
888 for (Subnets sub : transportZone.getSubnets()) {
889 if (sub.getVteps() != null && !sub.getVteps().isEmpty()) {
890 for (Vteps vtepLocal : sub.getVteps()) {
891 for (Vteps vtepRemote : sub.getVteps()) {
892 if (!vtepLocal.equals(vtepRemote)) {
893 InternalTunnelKey key = new InternalTunnelKey(vtepRemote.getDpnId(),
894 vtepLocal.getDpnId(), tunType);
895 InstanceIdentifier<InternalTunnel> intIID =
896 InstanceIdentifier.builder(TunnelList.class)
897 .child(InternalTunnel.class, key).build();
898 Optional<InternalTunnel> tunnelsOptional =
899 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, intIID, dataBroker);
900 if (tunnelsOptional.isPresent()) {
901 List<String> tunnelInterfaceNames = tunnelsOptional
902 .get().getTunnelInterfaceNames();
903 if (tunnelInterfaceNames != null && !tunnelInterfaceNames.isEmpty()) {
904 String tunnelInterfaceName = tunnelInterfaceNames.get(0);
905 LOG.trace("Internal Tunnel added {}", tunnelInterfaceName);
906 tunnels.add(tunnelInterfaceName);
911 if (hwVteps != null && !hwVteps.isEmpty()) {
912 for (HwVtep hwVtep : hwVteps) {
913 tunnels.add(getExtTunnel(hwVtep.getNodeId(), vtepLocal.getDpnId().toString(),
914 tunType, dataBroker));
915 tunnels.add(getExtTunnel(vtepLocal.getDpnId().toString(), hwVtep.getNodeId(),
916 tunType, dataBroker));
924 for (HwVtep hwVtep : hwVteps) {
925 for (HwVtep hwVtepOther : hwVteps) {
926 if (!hwVtep.getHwIp().equals(hwVtepOther.getHwIp())) {
927 tunnels.add(getExtTunnel(hwVtep.getNodeId(), hwVtepOther.getNodeId(),
928 tunType, dataBroker));
929 tunnels.add(getExtTunnel(hwVtepOther.getNodeId(), hwVtep.getNodeId(),
930 tunType, dataBroker));
939 public static List<String> getInternalTunnelsofTzone(String tzone, DataBroker dataBroker) {
940 List<String> tunnels = new ArrayList<>();
941 LOG.trace("Getting internal tunnels of {}",tzone);
942 InstanceIdentifier<TransportZone> path = InstanceIdentifier.builder(TransportZones.class)
943 .child(TransportZone.class, new TransportZoneKey(tzone)).build();
944 Optional<TransportZone> transportZoneOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
946 if (transportZoneOptional.isPresent()) {
947 TransportZone transportZone = transportZoneOptional.get();
948 if (transportZone.getSubnets() != null && !transportZone.getSubnets().isEmpty()) {
949 for (Subnets sub : transportZone.getSubnets()) {
950 if (sub.getVteps() != null && !sub.getVteps().isEmpty()) {
951 for (Vteps vtepLocal : sub.getVteps()) {
952 for (Vteps vtepRemote : sub.getVteps()) {
953 if (!vtepLocal.equals(vtepRemote)) {
954 InternalTunnelKey key =
955 new InternalTunnelKey(vtepRemote.getDpnId(), vtepLocal.getDpnId(),
956 transportZone.getTunnelType());
957 InstanceIdentifier<InternalTunnel> intIID =
958 InstanceIdentifier.builder(TunnelList.class)
959 .child(InternalTunnel.class, key).build();
960 Optional<InternalTunnel> tunnelsOptional =
961 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, intIID, dataBroker);
962 if (tunnelsOptional.isPresent()) {
963 List<String> tunnelInterfaceNames = tunnelsOptional.get()
964 .getTunnelInterfaceNames();
965 if (tunnelInterfaceNames != null && !tunnelInterfaceNames.isEmpty()) {
966 String tunnelInterfaceName = tunnelInterfaceNames.get(0);
967 LOG.trace("Internal Tunnel added {}", tunnelInterfaceName);
968 tunnels.add(tunnelInterfaceName);
981 private static String getExtTunnel(String nodeId, String dpId,Class<? extends TunnelTypeBase> tunType, DataBroker
983 LOG.trace("getting ext tunnel for {} and dpId {}",nodeId,dpId);
984 ExternalTunnelKey key = getExternalTunnelKey(dpId, nodeId, tunType);
985 InstanceIdentifier<ExternalTunnel> intIID = InstanceIdentifier.builder(ExternalTunnelList.class)
986 .child(ExternalTunnel.class, key).build();
987 Optional<ExternalTunnel> tunnelsOptional =
988 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, intIID, dataBroker);
989 if (tunnelsOptional.isPresent()) {
990 String tunnelInterfaceName = tunnelsOptional.get().getTunnelInterfaceName();
991 LOG.trace("ext tunnel returned {} ", tunnelInterfaceName);
992 return tunnelInterfaceName;
997 @SuppressFBWarnings("RV_CHECK_FOR_POSITIVE_INDEXOF")
998 public static ExternalTunnelKey getExternalTunnelKey(String dst , String src,
999 Class<? extends TunnelTypeBase> tunType) {
1000 final int srcIndex = src.indexOf("physicalswitch");
1002 src = src.substring(0, srcIndex - 1);
1004 final int dstIndex = dst.indexOf("physicalswitch");
1006 dst = dst.substring(0, dstIndex - 1);
1008 return new ExternalTunnelKey(dst, src, tunType);
1011 public static List<TunnelEndPoints> getTEPsForDpn(BigInteger srcDpn, Collection<DPNTEPsInfo> dpnList) {
1012 List<TunnelEndPoints> tunnelEndPoints = new ArrayList<>();
1013 for (DPNTEPsInfo dpn : dpnList) {
1014 if (dpn.getDPNID().equals(srcDpn)) {
1015 tunnelEndPoints.addAll(dpn.getTunnelEndPoints());
1016 return tunnelEndPoints ;
1022 public static List<InternalTunnel> getAllInternalTunnels(DataBroker dataBroker) {
1023 List<InternalTunnel> result = null;
1024 InstanceIdentifier<TunnelList> iid = InstanceIdentifier.builder(TunnelList.class).build();
1025 Optional<TunnelList> tunnelList = read(LogicalDatastoreType.CONFIGURATION, iid, dataBroker);
1027 if (tunnelList.isPresent()) {
1028 result = tunnelList.get().getInternalTunnel();
1030 if (result == null) {
1031 result = Collections.emptyList();
1036 public static InternalTunnel getInternalTunnel(String interfaceName, DataBroker broker) {
1037 InternalTunnel internalTunnel = ITM_CACHE.getInternalTunnel(interfaceName);
1038 if (internalTunnel == null) {
1039 updateTunnelsCache(broker);
1040 internalTunnel = ITM_CACHE.getInternalTunnel(interfaceName);
1042 return internalTunnel;
1045 public static ExternalTunnel getExternalTunnel(String interfaceName, DataBroker broker) {
1046 ExternalTunnel externalTunnel = ITM_CACHE.getExternalTunnel(interfaceName);
1047 if (externalTunnel == null) {
1048 updateTunnelsCache(broker);
1049 externalTunnel = ITM_CACHE.getExternalTunnel(interfaceName);
1051 return externalTunnel;
1054 private static List<ExternalTunnel> getAllExternalTunnels(DataBroker dataBroker) {
1055 List<ExternalTunnel> result = null;
1056 InstanceIdentifier<ExternalTunnelList> iid = InstanceIdentifier.builder(ExternalTunnelList.class).build();
1057 Optional<ExternalTunnelList> tunnelList = read(LogicalDatastoreType.CONFIGURATION, iid, dataBroker);
1058 if (tunnelList.isPresent()) {
1059 result = tunnelList.get().getExternalTunnel();
1061 if (result == null) {
1062 result = Collections.emptyList();
1067 public static String convertTunnelTypetoString(Class<? extends TunnelTypeBase> tunType) {
1068 String tunnelType = ITMConstants.TUNNEL_TYPE_VXLAN;
1069 if (tunType.equals(TunnelTypeVxlan.class)) {
1070 tunnelType = ITMConstants.TUNNEL_TYPE_VXLAN ;
1071 } else if (tunType.equals(TunnelTypeGre.class)) {
1072 tunnelType = ITMConstants.TUNNEL_TYPE_GRE ;
1073 } else if (tunType.equals(TunnelTypeMplsOverGre.class)) {
1074 tunnelType = ITMConstants.TUNNEL_TYPE_MPLSoGRE;
1075 } else if (tunType.equals(TunnelTypeLogicalGroup.class)) {
1076 tunnelType = ITMConstants.TUNNEL_TYPE_LOGICAL_GROUP_VXLAN;
1082 public static boolean isItmIfType(Class<? extends InterfaceType> ifType) {
1083 return ifType != null && ifType.isAssignableFrom(Tunnel.class);
1086 public static StateTunnelListKey getTunnelStateKey(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
1087 .interfaces.rev140508.interfaces.state.Interface iface) {
1088 StateTunnelListKey key = null;
1089 if (isItmIfType(iface.getType())) {
1090 key = new StateTunnelListKey(iface.getName());
1095 private static void updateTunnelsCache(DataBroker broker) {
1096 List<InternalTunnel> internalTunnels = getAllInternalTunnels(broker);
1097 for (InternalTunnel tunnel : internalTunnels) {
1098 ITM_CACHE.addInternalTunnel(tunnel);
1100 List<ExternalTunnel> externalTunnels = getAllExternalTunnels(broker);
1101 for (ExternalTunnel tunnel : externalTunnels) {
1102 ITM_CACHE.addExternalTunnel(tunnel);
1106 public static Interface getInterface(
1107 String name, IInterfaceManager ifaceManager) {
1108 Interface result = ITM_CACHE.getInterface(name);
1109 if (result == null) {
1110 result = ifaceManager.getInterfaceInfoFromConfigDataStore(name);
1111 if (result != null) {
1112 ITM_CACHE.addInterface(result);
1118 public static List<DcGatewayIp> getDcGatewayIpList(DataBroker broker) {
1119 InstanceIdentifier<DcGatewayIpList> dcGatewayIpListid =
1120 InstanceIdentifier.builder(DcGatewayIpList.class).build();
1121 Optional<DcGatewayIpList> dcGatewayIpListConfig =
1122 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, dcGatewayIpListid, broker);
1123 if (dcGatewayIpListConfig.isPresent()) {
1124 DcGatewayIpList containerList = dcGatewayIpListConfig.get();
1125 if (containerList != null) {
1126 return containerList.getDcGatewayIp();
1132 public static boolean falseIfNull(Boolean value) {
1133 return value == null ? false : value;
1136 public static <T> List<T> getIntersection(List<T> list1, List<T> list2) {
1137 List<T> list = new ArrayList<>();
1138 for (T iter : list1) {
1139 if (list2.contains(iter)) {
1143 LOG.debug(" getIntersection - L1 {}, L2 - {}, Intersection - {}", list1, list2, list);
1147 public static void addTransportZoneMembership(List<TzMembership> zones, String zoneName) {
1148 zones.add(new TzMembershipBuilder().setZoneName(zoneName).build());
1151 public static List<TzMembership> createTransportZoneMembership(String zoneName) {
1152 List<TzMembership> zones = new ArrayList<>();
1153 zones.add(new TzMembershipBuilder().setZoneName(zoneName).build());
1158 * Gets the transport zone in TepsNotHosted list in the Operational Datastore, based on transport zone name.
1160 * @param unknownTz transport zone name
1162 * @param dataBroker data broker handle to perform read operations on Oper datastore
1164 * @return the TepsInNotHostedTransportZone object in the TepsNotHosted list in Oper DS
1166 public static TepsInNotHostedTransportZone getUnknownTransportZoneFromITMOperDS(
1167 String unknownTz, DataBroker dataBroker) {
1168 InstanceIdentifier<TepsInNotHostedTransportZone> unknownTzPath =
1169 InstanceIdentifier.builder(NotHostedTransportZones.class)
1170 .child(TepsInNotHostedTransportZone.class,
1171 new TepsInNotHostedTransportZoneKey(unknownTz)).build();
1172 Optional<TepsInNotHostedTransportZone> unknownTzOptional =
1173 ItmUtils.read(LogicalDatastoreType.OPERATIONAL, unknownTzPath, dataBroker);
1174 if (unknownTzOptional.isPresent()) {
1175 return unknownTzOptional.get();
1181 * Gets the bridge datapath ID from Network topology Node's OvsdbBridgeAugmentation, in the Operational DS.
1183 * @param node Network Topology Node
1185 * @param bridge bridge name
1187 * @param dataBroker data broker handle to perform operations on datastore
1189 * @return the datapath ID of bridge in string form
1191 public static String getBridgeDpid(Node node, String bridge, DataBroker dataBroker) {
1192 OvsdbBridgeAugmentation ovsdbBridgeAugmentation = null;
1193 Node bridgeNode = null;
1194 String datapathId = null;
1196 NodeId ovsdbNodeId = node.key().getNodeId();
1198 NodeId brNodeId = new NodeId(ovsdbNodeId.getValue()
1199 + "/" + ITMConstants.BRIDGE_URI_PREFIX + "/" + bridge);
1201 InstanceIdentifier<Node> bridgeIid =
1203 .create(NetworkTopology.class)
1204 .child(Topology.class, new TopologyKey(IfmConstants.OVSDB_TOPOLOGY_ID))
1205 .child(Node.class,new NodeKey(brNodeId));
1207 Optional<Node> opBridgeNode = ItmUtils.read(LogicalDatastoreType.OPERATIONAL, bridgeIid, dataBroker);
1209 if (opBridgeNode.isPresent()) {
1210 bridgeNode = opBridgeNode.get();
1212 if (bridgeNode != null) {
1213 ovsdbBridgeAugmentation = bridgeNode.augmentation(OvsdbBridgeAugmentation.class);
1216 if (ovsdbBridgeAugmentation != null && ovsdbBridgeAugmentation.getDatapathId() != null) {
1217 datapathId = ovsdbBridgeAugmentation.getDatapathId().getValue();
1223 * Gets the Network topology Node from Operational Datastore
1224 * based on Bridge Augmentation.
1226 * @param bridgeAugmentation bridge augmentation of OVSDB node
1228 * @param dataBroker data broker handle to perform operations on datastore
1230 * @return the Network Topology Node i.e. OVSDB node which is managing the specified bridge
1232 public static Node getOvsdbNode(OvsdbBridgeAugmentation bridgeAugmentation,
1233 DataBroker dataBroker) {
1234 Node ovsdbNode = null;
1235 Optional<Node> opOvsdbNode = Optional.absent();
1236 if (bridgeAugmentation != null) {
1237 InstanceIdentifier<Node> ovsdbNodeIid =
1238 (InstanceIdentifier<Node>) bridgeAugmentation.getManagedBy().getValue();
1239 opOvsdbNode = ItmUtils.read(LogicalDatastoreType.OPERATIONAL, ovsdbNodeIid, dataBroker);
1241 if (opOvsdbNode.isPresent()) {
1242 ovsdbNode = opOvsdbNode.get();
1248 * Gets the bridge datapath ID in string form from
1249 * Network topology Node's OvsdbBridgeAugmentation in the Operational DS.
1251 * @param augmentedNode Ovsdb Augmented Network Topology Node
1253 * @return the datapath ID of bridge in string form
1255 public static String getStrDatapathId(OvsdbBridgeAugmentation augmentedNode) {
1256 String datapathId = null;
1257 if (augmentedNode != null && augmentedNode.getDatapathId() != null) {
1258 datapathId = augmentedNode.getDatapathId().getValue();
1264 * Returns the dummy subnet (255.255.255.255/32) as IpPrefix object.
1266 * @return the dummy subnet (255.255.255.255/32) in IpPrefix object
1268 public static IpPrefix getDummySubnet() {
1269 return DUMMY_IP_PREFIX;
1273 * Deletes the transport zone from Configuration datastore.
1275 * @param tzName transport zone name
1276 * @param dataBroker data broker handle to perform operations on datastore
1278 public static void deleteTransportZoneFromConfigDS(String tzName, DataBroker dataBroker) {
1279 // check whether transport-zone exists in config DS.
1280 TransportZone transportZoneFromConfigDS = ItmUtils.getTransportZoneFromConfigDS(tzName, dataBroker);
1281 if (transportZoneFromConfigDS != null) {
1282 // it exists, delete default-TZ now
1283 InstanceIdentifier<TransportZone> path = InstanceIdentifier.builder(TransportZones.class)
1284 .child(TransportZone.class, new TransportZoneKey(tzName)).build();
1285 LOG.debug("Removing {} transport-zone from config DS.", tzName);
1287 SingleTransactionDataBroker.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, path);
1288 } catch (TransactionCommitFailedException e) {
1289 LOG.error("deleteTransportZoneFromConfigDS failed. {} could not be deleted.", tzName, e);
1295 * Validates the tunnelType argument and returnsTunnelTypeBase class object
1296 * corresponding to tunnelType obtained in String format.
1298 * @param tunnelType type of tunnel in string form
1300 * @return tunnel-type in TunnelTypeBase object
1302 public static Class<? extends TunnelTypeBase> getTunnelType(String tunnelType) {
1303 // validate tunnelType string, in case it is NULL or empty, then
1304 // take VXLAN tunnel type by default
1305 if (tunnelType == null || tunnelType.isEmpty()) {
1306 return TUNNEL_TYPE_MAP.get(ITMConstants.TUNNEL_TYPE_VXLAN);
1307 } else if (!tunnelType.equals(ITMConstants.TUNNEL_TYPE_VXLAN)
1308 && !tunnelType.equals(ITMConstants.TUNNEL_TYPE_GRE)) {
1309 // if tunnel type is some incorrect value, then
1310 // take VXLAN tunnel type by default
1311 return TUNNEL_TYPE_MAP.get(ITMConstants.TUNNEL_TYPE_VXLAN);
1314 // return TunnelTypeBase object corresponding to tunnel-type
1315 return TUNNEL_TYPE_MAP.get(tunnelType);
1318 public static List<TzMembership> removeTransportZoneMembership(TunnelEndPoints endPts, List<TzMembership> zones) {
1319 LOG.trace(" RemoveTransportZoneMembership TEPs {}, Membership to be removed {} ", endPts, zones);
1320 List<TzMembership> existingTzList = new ArrayList<>(endPts.getTzMembership()) ;
1321 for (TzMembership membership : zones) {
1322 existingTzList.remove(new TzMembershipBuilder().setZoneName(membership.getZoneName()).build());
1324 LOG.debug("Modified Membership List {}", existingTzList);
1325 return existingTzList;
1328 public static List<TzMembership> getOriginalTzMembership(TunnelEndPoints srcTep, BigInteger dpnId,
1329 Collection<DPNTEPsInfo> meshedDpnList) {
1330 LOG.trace("Original Membership for source DPN {}, source TEP {}", dpnId, srcTep);
1331 for (DPNTEPsInfo dstDpn : meshedDpnList) {
1332 if (dpnId.equals(dstDpn.getDPNID())) {
1333 List<TunnelEndPoints> endPts = dstDpn.getTunnelEndPoints();
1334 for (TunnelEndPoints tep : endPts) {
1335 if (tep.getIpAddress().equals(srcTep.getIpAddress())) {
1336 LOG.debug("Original Membership size {}", tep.getTzMembership().size()) ;
1337 return tep.getTzMembership();
1345 public static StateTunnelList buildStateTunnelList(StateTunnelListKey tlKey, String name, boolean state,
1346 TunnelOperStatus tunOpStatus, IInterfaceManager ifaceManager,
1347 DataBroker broker) {
1348 StateTunnelListBuilder stlBuilder = new StateTunnelListBuilder();
1349 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface =
1350 ItmUtils.getInterface(name, ifaceManager);
1351 IfTunnel ifTunnel = iface.augmentation(IfTunnel.class);
1352 ParentRefs parentRefs = iface.augmentation(ParentRefs.class);
1353 if (ifTunnel == null || parentRefs == null) {
1356 DstInfoBuilder dstInfoBuilder = new DstInfoBuilder();
1357 SrcInfoBuilder srcInfoBuilder = new SrcInfoBuilder();
1358 dstInfoBuilder.setTepIp(ifTunnel.getTunnelDestination());
1359 srcInfoBuilder.setTepIp(ifTunnel.getTunnelSource());
1360 // TODO: Add/Improve logic for device type
1361 InternalTunnel internalTunnel = ItmUtils.ITM_CACHE.getInternalTunnel(name);
1362 ExternalTunnel externalTunnel = ItmUtils.ITM_CACHE.getExternalTunnel(name);
1363 if (internalTunnel == null && externalTunnel == null) {
1364 // both not present in cache. let us update and try again.
1365 ItmUtils.updateTunnelsCache(broker);
1366 internalTunnel = ItmUtils.ITM_CACHE.getInternalTunnel(name);
1367 externalTunnel = ItmUtils.ITM_CACHE.getExternalTunnel(name);
1369 if (internalTunnel != null) {
1370 srcInfoBuilder.setTepDeviceId(internalTunnel.getSourceDPN().toString())
1371 .setTepDeviceType(TepTypeInternal.class);
1372 dstInfoBuilder.setTepDeviceId(internalTunnel.getDestinationDPN().toString())
1373 .setTepDeviceType(TepTypeInternal.class);
1374 stlBuilder.setTransportType(internalTunnel.getTransportType());
1375 } else if (externalTunnel != null) {
1376 ExternalTunnel tunnel = ItmUtils.ITM_CACHE.getExternalTunnel(name);
1377 srcInfoBuilder.setTepDeviceId(tunnel.getSourceDevice())
1378 .setTepDeviceType(getDeviceType(tunnel.getSourceDevice()));
1379 dstInfoBuilder.setTepDeviceId(tunnel.getDestinationDevice())
1380 .setTepDeviceType(getDeviceType(tunnel.getDestinationDevice()))
1381 .setTepIp(ifTunnel.getTunnelDestination());
1382 stlBuilder.setTransportType(tunnel.getTransportType());
1384 stlBuilder.withKey(tlKey).setTunnelInterfaceName(name).setOperState(tunOpStatus).setTunnelState(state)
1385 .setDstInfo(dstInfoBuilder.build()).setSrcInfo(srcInfoBuilder.build());
1386 return stlBuilder.build();
1389 private static Class<? extends TepTypeBase> getDeviceType(String device) {
1390 if (device.startsWith("hwvtep")) {
1391 return TepTypeHwvtep.class;
1392 } else if (InetAddresses.isInetAddress(device)) {
1393 // In case of external tunnel, destination-device will be of IP address type.
1394 return TepTypeExternal.class;
1396 return TepTypeInternal.class;
1400 public static InstanceIdentifier<StateTunnelList> buildStateTunnelListId(StateTunnelListKey tlKey) {
1401 return InstanceIdentifier.builder(TunnelsState.class)
1402 .child(StateTunnelList.class, tlKey).build();
1406 public static Optional<InternalTunnel> getInternalTunnelFromDS(BigInteger srcDpn, BigInteger destDpn,
1407 Class<? extends TunnelTypeBase> type,
1408 DataBroker dataBroker) {
1409 InstanceIdentifier<InternalTunnel> pathLogicTunnel = InstanceIdentifier.create(TunnelList.class)
1410 .child(InternalTunnel.class,
1411 new InternalTunnelKey(destDpn, srcDpn, type));
1412 //TODO: need to be replaced by cached copy
1413 return ItmUtils.read(LogicalDatastoreType.CONFIGURATION, pathLogicTunnel, dataBroker);
1416 public static boolean isTunnelAggregationUsed(Class<? extends TunnelTypeBase> tunType) {
1417 return ItmTunnelAggregationHelper.isTunnelAggregationEnabled()
1418 && (tunType.isAssignableFrom(TunnelTypeVxlan.class)
1419 || tunType.isAssignableFrom(TunnelTypeLogicalGroup.class));
1422 public static List<TunnelOptions> buildTunnelOptions(TunnelEndPoints tep, ItmConfig itmConfig) {
1423 List<TunnelOptions> tunOptions = new ArrayList<>();
1425 String tos = tep.getOptionTunnelTos();
1427 tos = itmConfig.getDefaultTunnelTos();
1429 /* populate tos option only if its not default value of 0 */
1430 if (tos != null && !tos.equals("0")) {
1431 TunnelOptionsBuilder optionsBuilder = new TunnelOptionsBuilder();
1432 optionsBuilder.withKey(new TunnelOptionsKey("tos"));
1433 optionsBuilder.setTunnelOption("tos");
1434 optionsBuilder.setValue(tos);
1435 tunOptions.add(optionsBuilder.build());
1438 if (tep.getTunnelType() == TunnelTypeVxlan.class && itmConfig.isGpeExtensionEnabled()) {
1439 TunnelOptionsBuilder optionsBuilder = new TunnelOptionsBuilder();
1440 optionsBuilder.withKey(new TunnelOptionsKey("exts"));
1441 optionsBuilder.setTunnelOption("exts");
1442 optionsBuilder.setValue("gpe");
1443 tunOptions.add(optionsBuilder.build());
1445 return tunOptions.isEmpty() ? null : tunOptions;
1448 public static ExternalTunnel getExternalTunnelbyExternalTunnelKey(ExternalTunnelKey externalTunnelKey,
1449 InstanceIdentifier<ExternalTunnel> path,
1450 DataBroker dataBroker) {
1451 ExternalTunnel exTunnel = ITM_CACHE.getExternalTunnelKeyToExternalTunnels().get(externalTunnelKey);
1452 if (exTunnel == null) {
1453 Optional<ExternalTunnel> ext = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
1454 if (ext.isPresent()) {
1455 exTunnel = ext.get();
1461 public static List<DPNTEPsInfo> getDpnTEPsInfos(DataBroker dataBroker) {
1462 InstanceIdentifier<DpnEndpoints> iid = InstanceIdentifier.builder(DpnEndpoints.class).build();
1463 Optional<DpnEndpoints> dpnEndpoints = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, iid, dataBroker);
1464 if (dpnEndpoints.isPresent()) {
1465 return dpnEndpoints.get().getDPNTEPsInfo();
1467 return new ArrayList<>();
1471 public static InstanceIdentifier<TransportZone> getTZInstanceIdentifier(String tzName) {
1472 return InstanceIdentifier.builder(TransportZones.class).child(TransportZone.class,
1473 new TransportZoneKey(tzName)).build();
1477 * Returns the transport zone from Configuration datastore.
1479 * @param tzName transport zone name
1480 * @param dataBroker data broker handle to perform operations on datastore
1481 * @return the TransportZone object in Config DS
1483 // FIXME: Better is to implement cache to avoid datastore read.
1484 public static TransportZone getTransportZoneFromConfigDS(String tzName, DataBroker dataBroker) {
1485 InstanceIdentifier<TransportZone> tzonePath = getTZInstanceIdentifier(tzName);
1486 Optional<TransportZone> transportZoneOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, tzonePath,
1488 if (transportZoneOptional.isPresent()) {
1489 return transportZoneOptional.get();
1494 public static Class<? extends TunnelTypeBase> convertStringToTunnelType(String tunnelType) {
1495 Class<? extends TunnelTypeBase> tunType = TunnelTypeVxlan.class;
1496 if (STRING_CLASS_IMMUTABLE_BI_MAP.containsKey(tunnelType)) {
1497 tunType = STRING_CLASS_IMMUTABLE_BI_MAP.get(tunnelType);