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.interfacemanager.globals.IfmConstants;
39 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
40 import org.opendaylight.genius.itm.api.IITMProvider;
41 import org.opendaylight.genius.itm.cache.DPNTEPsInfoCache;
42 import org.opendaylight.genius.itm.confighelpers.HwVtep;
43 import org.opendaylight.genius.itm.confighelpers.ItmTunnelAggregationHelper;
44 import org.opendaylight.genius.itm.globals.ITMConstants;
45 import org.opendaylight.genius.mdsalutil.ActionInfo;
46 import org.opendaylight.genius.mdsalutil.FlowEntity;
47 import org.opendaylight.genius.mdsalutil.InstructionInfo;
48 import org.opendaylight.genius.mdsalutil.MDSALUtil;
49 import org.opendaylight.genius.mdsalutil.MatchInfo;
50 import org.opendaylight.genius.mdsalutil.NwConstants;
51 import org.opendaylight.genius.mdsalutil.actions.ActionPuntToController;
52 import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
53 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
54 import org.opendaylight.genius.mdsalutil.matches.MatchTunnelId;
55 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel;
56 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
57 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder;
58 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
59 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefixBuilder;
60 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType;
61 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
62 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
63 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
64 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
65 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlanBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnel;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnelBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefs;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefsBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelMonitoringTypeBase;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeGre;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeLogicalGroup;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeMplsOverGre;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.interfaces._interface.NodeIdentifier;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.interfaces._interface.NodeIdentifierBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.interfaces._interface.NodeIdentifierKey;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.tunnel.optional.params.TunnelOptions;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.tunnel.optional.params.TunnelOptionsBuilder;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.tunnel.optional.params.TunnelOptionsKey;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.ItmConfig;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.VtepConfigSchemas;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.VtepIpPools;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.VtepConfigSchema;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.VtepConfigSchemaBuilder;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.VtepConfigSchemaKey;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.vtep.config.schema.DpnIds;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.vtep.config.schema.DpnIdsBuilder;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.vtep.config.schema.DpnIdsKey;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.ip.pools.VtepIpPool;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.ip.pools.VtepIpPoolKey;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpointsBuilder;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.ExternalTunnelList;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeBase;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeExternal;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeHwvtep;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeInternal;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelList;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelOperStatus;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelsState;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoBuilder;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoKey;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPointsBuilder;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPointsKey;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.tunnel.end.points.TzMembership;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.tunnel.end.points.TzMembershipBuilder;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnel;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnelBuilder;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnelKey;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnel;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnelBuilder;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnelKey;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelList;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelListBuilder;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelListKey;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.state.tunnel.list.DstInfoBuilder;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.state.tunnel.list.SrcInfoBuilder;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.DcGatewayIpList;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZones;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.dc.gateway.ip.list.DcGatewayIp;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TepsNotHostedInTransportZone;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TepsNotHostedInTransportZoneKey;
129 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZone;
130 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZoneKey;
131 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.Subnets;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.Vteps;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
134 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
135 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
136 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
137 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
138 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
139 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
140 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
141 import org.opendaylight.yangtools.yang.binding.DataObject;
142 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
143 import org.slf4j.Logger;
144 import org.slf4j.LoggerFactory;
146 public final class ItmUtils {
148 private static final Logger LOG = LoggerFactory.getLogger(ItmUtils.class);
150 private static final String TUNNEL = "tun";
151 private static final IpPrefix DUMMY_IP_PREFIX = IpPrefixBuilder.getDefaultInstance(ITMConstants.DUMMY_PREFIX);
152 private static final long DEFAULT_MONITORING_INTERVAL = 100L;
153 public static final ItmCache ITM_CACHE = new ItmCache();
155 public static final ImmutableMap<String, Class<? extends TunnelTypeBase>>
157 new ImmutableMap.Builder<String, Class<? extends TunnelTypeBase>>()
158 .put(ITMConstants.TUNNEL_TYPE_GRE, TunnelTypeGre.class)
159 .put(ITMConstants.TUNNEL_TYPE_MPLSoGRE, TunnelTypeMplsOverGre.class)
160 .put(ITMConstants.TUNNEL_TYPE_VXLAN, TunnelTypeVxlan.class)
163 private static final BiMap<String,Class<? extends TunnelTypeBase>> STRING_CLASS_IMMUTABLE_BI_MAP =
164 ImmutableBiMap.copyOf(TUNNEL_TYPE_MAP);
169 public static final FutureCallback<Void> DEFAULT_CALLBACK = new FutureCallback<Void>() {
171 public void onSuccess(Void result) {
172 LOG.debug("Success in Datastore write operation");
176 public void onFailure(@Nonnull Throwable error) {
177 LOG.error("Error in Datastore write operation", error);
181 @SuppressWarnings("checkstyle:IllegalCatch")
182 public static <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType,
183 InstanceIdentifier<T> path, DataBroker broker) {
184 try (ReadOnlyTransaction tx = broker.newReadOnlyTransaction()) {
185 return tx.read(datastoreType, path).get();
186 } catch (Exception e) {
187 throw new RuntimeException(e);
191 public static <T extends DataObject> void asyncWrite(LogicalDatastoreType datastoreType,
192 InstanceIdentifier<T> path, T data, DataBroker broker,
193 FutureCallback<Void> callback) {
194 WriteTransaction tx = broker.newWriteOnlyTransaction();
195 tx.put(datastoreType, path, data, true);
196 Futures.addCallback(tx.submit(), callback);
199 public static <T extends DataObject> void asyncUpdate(LogicalDatastoreType datastoreType,
200 InstanceIdentifier<T> path, T data, DataBroker broker,
201 FutureCallback<Void> callback) {
202 WriteTransaction tx = broker.newWriteOnlyTransaction();
203 tx.merge(datastoreType, path, data, true);
204 Futures.addCallback(tx.submit(), callback);
207 public static <T extends DataObject> void asyncDelete(LogicalDatastoreType datastoreType,
208 InstanceIdentifier<T> path, DataBroker broker,
209 FutureCallback<Void> callback) {
210 WriteTransaction tx = broker.newWriteOnlyTransaction();
211 tx.delete(datastoreType, path);
212 Futures.addCallback(tx.submit(), callback);
215 public static <T extends DataObject> void asyncBulkRemove(final DataBroker broker,
216 final LogicalDatastoreType datastoreType,
217 List<InstanceIdentifier<T>> pathList,
218 FutureCallback<Void> callback) {
219 if (!pathList.isEmpty()) {
220 WriteTransaction tx = broker.newWriteOnlyTransaction();
221 for (InstanceIdentifier<T> path : pathList) {
222 tx.delete(datastoreType, path);
224 Futures.addCallback(tx.submit(), callback);
228 public static String getInterfaceName(final BigInteger datapathid, final String portName, final Integer vlanId) {
229 return String.format("%s:%s:%s", datapathid, portName, vlanId);
232 public static BigInteger getDpnIdFromInterfaceName(String interfaceName) {
233 String[] dpnStr = interfaceName.split(":");
234 return new BigInteger(dpnStr[0]);
237 public static String getTrunkInterfaceName(String parentInterfaceName,
238 String localHostName, String remoteHostName, String tunnelType) {
239 String tunnelTypeStr;
240 if (tunnelType.contains("TunnelTypeGre")) {
241 tunnelTypeStr = ITMConstants.TUNNEL_TYPE_GRE;
242 } else if (tunnelType.contains("TunnelTypeLogicalGroup")) {
243 tunnelTypeStr = ITMConstants.TUNNEL_TYPE_LOGICAL_GROUP_VXLAN;
245 tunnelTypeStr = ITMConstants.TUNNEL_TYPE_VXLAN;
247 String trunkInterfaceName = String.format("%s:%s:%s:%s", parentInterfaceName, localHostName,
248 remoteHostName, tunnelTypeStr);
249 LOG.trace("trunk interface name is {}", trunkInterfaceName);
250 trunkInterfaceName = String.format("%s%s", TUNNEL, getUniqueIdString(trunkInterfaceName));
251 return trunkInterfaceName;
254 public static void releaseIdForTrunkInterfaceName(String parentInterfaceName,
255 String localHostName, String remoteHostName, String tunnelType) {
256 String tunnelTypeStr;
257 if (tunnelType.contains("TunnelTypeGre")) {
258 tunnelTypeStr = ITMConstants.TUNNEL_TYPE_GRE;
260 tunnelTypeStr = ITMConstants.TUNNEL_TYPE_VXLAN;
262 String trunkInterfaceName = String.format("%s:%s:%s:%s", parentInterfaceName, localHostName,
263 remoteHostName, tunnelTypeStr);
264 LOG.trace("Releasing Id for trunkInterface - {}", trunkInterfaceName);
267 public static String getLogicalTunnelGroupName(BigInteger srcDpnId, BigInteger destDpnId) {
268 String tunnelTypeStr = ITMConstants.TUNNEL_TYPE_LOGICAL_GROUP_VXLAN;
269 String groupName = String.format("%s:%s:%s", srcDpnId.toString(), destDpnId.toString(), tunnelTypeStr);
270 LOG.trace("logical tunnel group name is {}", groupName);
271 groupName = String.format("%s%s", TUNNEL, getUniqueIdString(groupName));
275 public static InetAddress getInetAddressFromIpAddress(IpAddress ip) {
276 return InetAddresses.forString(String.valueOf(ip.getValue()));
279 public static InstanceIdentifier<DPNTEPsInfo> getDpnTepInstance(BigInteger dpIdKey) {
280 return InstanceIdentifier.builder(DpnEndpoints.class).child(DPNTEPsInfo.class, new DPNTEPsInfoKey(dpIdKey))
284 public static DPNTEPsInfo createDPNTepInfo(BigInteger dpId, List<TunnelEndPoints> endpoints) {
285 return new DPNTEPsInfoBuilder().setKey(new DPNTEPsInfoKey(dpId)).setTunnelEndPoints(endpoints).build();
288 public static TunnelEndPoints createTunnelEndPoints(BigInteger dpnId, IpAddress ipAddress, String portName,
289 boolean isOfTunnel, int vlanId, IpPrefix prefix,
290 IpAddress gwAddress, List<TzMembership> zones,
291 Class<? extends TunnelTypeBase> tunnelType,
293 // when Interface Mgr provides support to take in Dpn Id
294 return new TunnelEndPointsBuilder().setKey(new TunnelEndPointsKey(ipAddress, portName,tunnelType, vlanId))
295 .setSubnetMask(prefix).setGwIpAddress(gwAddress).setTzMembership(zones)
296 .setOptionOfTunnel(isOfTunnel).setInterfaceName(ItmUtils.getInterfaceName(dpnId, portName, vlanId))
297 .setTunnelType(tunnelType)
298 .setOptionTunnelTos(tos)
302 public static DpnEndpoints createDpnEndpoints(List<DPNTEPsInfo> dpnTepInfo) {
303 return new DpnEndpointsBuilder().setDPNTEPsInfo(dpnTepInfo).build();
306 public static InstanceIdentifier<Interface> buildId(String interfaceName) {
307 return InstanceIdentifier.builder(Interfaces.class).child(Interface.class, new InterfaceKey(interfaceName))
311 public static InstanceIdentifier<IfTunnel> buildTunnelId(String ifName) {
312 return InstanceIdentifier.builder(Interfaces.class)
313 .child(Interface.class, new InterfaceKey(ifName)).augmentation(IfTunnel.class).build();
316 public static Interface buildLogicalTunnelInterface(BigInteger dpn, String ifName, String desc, boolean enabled) {
317 InterfaceBuilder builder = new InterfaceBuilder().setKey(new InterfaceKey(ifName)).setName(ifName)
318 .setDescription(desc).setEnabled(enabled).setType(Tunnel.class);
319 ParentRefs parentRefs = new ParentRefsBuilder().setDatapathNodeIdentifier(dpn).build();
320 builder.addAugmentation(ParentRefs.class, parentRefs);
322 IfTunnel tunnel = new IfTunnelBuilder()
323 .setTunnelDestination(IpAddressBuilder.getDefaultInstance(ITMConstants.DUMMY_IP_ADDRESS))
324 .setTunnelSource(IpAddressBuilder.getDefaultInstance(ITMConstants.DUMMY_IP_ADDRESS)).setInternal(true)
325 .setMonitorEnabled(false).setTunnelInterfaceType(TunnelTypeLogicalGroup.class)
326 .setTunnelRemoteIpFlow(false).build();
327 builder.addAugmentation(IfTunnel.class, tunnel);
328 return builder.build();
331 public static Interface buildTunnelInterface(BigInteger dpn, String ifName, String desc, boolean enabled,
332 Class<? extends TunnelTypeBase> tunType, IpAddress localIp,
333 IpAddress remoteIp, IpAddress gatewayIp, Integer vlanId,
334 boolean internal, Boolean monitorEnabled,
335 Class<? extends TunnelMonitoringTypeBase> monitorProtocol,
336 Integer monitorInterval, boolean useOfTunnel,
337 List<TunnelOptions> tunOptions) {
339 return buildTunnelInterface(dpn, ifName, desc, enabled, tunType, localIp, remoteIp, gatewayIp, vlanId,
340 internal, monitorEnabled, monitorProtocol, monitorInterval, useOfTunnel, null,
344 public static Interface buildTunnelInterface(BigInteger dpn, String ifName, String desc, boolean enabled,
345 Class<? extends TunnelTypeBase> tunType, IpAddress localIp,
346 IpAddress remoteIp, IpAddress gatewayIp, Integer vlanId,
347 boolean internal, Boolean monitorEnabled,
348 Class<? extends TunnelMonitoringTypeBase> monitorProtocol,
349 Integer monitorInterval, boolean useOfTunnel, String parentIfaceName,
350 List<TunnelOptions> tunnelOptions) {
351 InterfaceBuilder builder = new InterfaceBuilder().setKey(new InterfaceKey(ifName)).setName(ifName)
352 .setDescription(desc).setEnabled(enabled).setType(Tunnel.class);
353 ParentRefs parentRefs =
354 new ParentRefsBuilder().setDatapathNodeIdentifier(dpn).setParentInterface(parentIfaceName).build();
355 builder.addAugmentation(ParentRefs.class, parentRefs);
356 Long monitoringInterval = null;
358 IfL2vlan l2vlan = new IfL2vlanBuilder().setVlanId(new VlanId(vlanId)).build();
359 builder.addAugmentation(IfL2vlan.class, l2vlan);
361 LOG.debug("buildTunnelInterface: monitorProtocol = {} and monitorInterval = {}",
362 monitorProtocol.getName(),monitorInterval);
364 if (monitorInterval != null) {
365 monitoringInterval = monitorInterval.longValue();
368 IfTunnel tunnel = new IfTunnelBuilder().setTunnelDestination(remoteIp).setTunnelGateway(gatewayIp)
369 .setTunnelSource(localIp).setTunnelInterfaceType(tunType).setInternal(internal)
370 .setMonitorEnabled(monitorEnabled).setMonitorProtocol(monitorProtocol)
371 .setMonitorInterval(monitoringInterval).setTunnelRemoteIpFlow(useOfTunnel)
372 .setTunnelOptions(tunnelOptions)
374 builder.addAugmentation(IfTunnel.class, tunnel);
375 return builder.build();
378 public static Interface buildHwTunnelInterface(String tunnelIfName, String desc, boolean enabled, String topoId,
379 String nodeId, Class<? extends TunnelTypeBase> tunType,
380 IpAddress srcIp, IpAddress destIp, IpAddress gwIp,
381 Boolean monitorEnabled,
382 Class<? extends TunnelMonitoringTypeBase> monitorProtocol,
383 Integer monitorInterval) {
384 InterfaceBuilder builder = new InterfaceBuilder().setKey(new InterfaceKey(tunnelIfName))
385 .setName(tunnelIfName).setDescription(desc).setEnabled(enabled).setType(Tunnel.class);
386 List<NodeIdentifier> nodeIds = new ArrayList<>();
387 NodeIdentifier hwNode = new NodeIdentifierBuilder().setKey(new NodeIdentifierKey(topoId))
388 .setTopologyId(topoId).setNodeId(nodeId).build();
390 ParentRefs parent = new ParentRefsBuilder().setNodeIdentifier(nodeIds).build();
391 builder.addAugmentation(ParentRefs.class, parent);
392 IfTunnel tunnel = new IfTunnelBuilder().setTunnelDestination(destIp).setTunnelGateway(gwIp)
393 .setTunnelSource(srcIp).setMonitorEnabled(monitorEnabled == null || monitorEnabled)
394 .setMonitorProtocol(monitorProtocol == null ? ITMConstants.DEFAULT_MONITOR_PROTOCOL : monitorProtocol)
395 .setMonitorInterval(DEFAULT_MONITORING_INTERVAL).setTunnelInterfaceType(tunType).setInternal(false)
397 builder.addAugmentation(IfTunnel.class, tunnel);
398 LOG.trace("iftunnel {} built from hwvtep {} ", tunnel, nodeId);
399 return builder.build();
402 public static InternalTunnel buildInternalTunnel(BigInteger srcDpnId, BigInteger dstDpnId,
403 Class<? extends TunnelTypeBase> tunType,
404 String trunkInterfaceName) {
405 return new InternalTunnelBuilder().setKey(new InternalTunnelKey(dstDpnId, srcDpnId, tunType))
406 .setDestinationDPN(dstDpnId)
407 .setSourceDPN(srcDpnId).setTransportType(tunType)
408 .setTunnelInterfaceNames(Collections.singletonList(trunkInterfaceName)).build();
411 public static ExternalTunnel buildExternalTunnel(String srcNode, String dstNode,
412 Class<? extends TunnelTypeBase> tunType,
413 String trunkInterfaceName) {
414 return new ExternalTunnelBuilder().setKey(
415 new ExternalTunnelKey(dstNode, srcNode, tunType))
416 .setSourceDevice(srcNode).setDestinationDevice(dstNode)
417 .setTunnelInterfaceName(trunkInterfaceName)
418 .setTransportType(tunType).build();
421 private static String getUniqueIdString(String idKey) {
422 return UUID.nameUUIDFromBytes(idKey.getBytes(StandardCharsets.UTF_8)).toString().substring(0, 12)
426 public static List<DPNTEPsInfo> getDpnTepListFromDpnId(DPNTEPsInfoCache dpnTEPsInfoCache, List<BigInteger> dpnIds) {
427 Collection<DPNTEPsInfo> meshedDpnList = dpnTEPsInfoCache.getAllPresent();
428 List<DPNTEPsInfo> cfgDpnList = new ArrayList<>();
429 for (BigInteger dpnId : dpnIds) {
430 for (DPNTEPsInfo teps : meshedDpnList) {
431 if (dpnId.equals(teps.getDPNID())) {
432 cfgDpnList.add(teps);
440 @SuppressWarnings("checkstyle:IllegalCatch")
441 public static void setUpOrRemoveTerminatingServiceTable(BigInteger dpnId, IMdsalApiManager mdsalManager,
443 String logmsg = addFlag ? "Installing" : "Removing";
444 LOG.trace("{}PUNT to Controller flow in DPN {} ", logmsg, dpnId);
445 List<ActionInfo> listActionInfo = new ArrayList<>();
446 listActionInfo.add(new ActionPuntToController());
449 List<MatchInfo> mkMatches = new ArrayList<>();
451 mkMatches.add(new MatchTunnelId(BigInteger.valueOf(ITMConstants.LLDP_SERVICE_ID)));
453 List<InstructionInfo> mkInstructions = new ArrayList<>();
454 mkInstructions.add(new InstructionApplyActions(listActionInfo));
456 FlowEntity terminatingServiceTableFlowEntity = MDSALUtil
457 .buildFlowEntity(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE,
458 getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE, ITMConstants.LLDP_SERVICE_ID),
459 5, String.format("%s:%d","ITM Flow Entry ", ITMConstants.LLDP_SERVICE_ID), 0, 0,
460 ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(ITMConstants.LLDP_SERVICE_ID)),
461 mkMatches, mkInstructions);
463 mdsalManager.installFlow(terminatingServiceTableFlowEntity);
465 mdsalManager.removeFlow(terminatingServiceTableFlowEntity);
467 } catch (Exception e) {
468 LOG.error("Error while setting up Table 36 for {}", dpnId, e);
472 private static String getFlowRef(long termSvcTable, int svcId) {
473 return String.valueOf(termSvcTable) + svcId;
476 public static InstanceIdentifier<VtepConfigSchema> getVtepConfigSchemaIdentifier(String schemaName) {
477 return InstanceIdentifier.builder(VtepConfigSchemas.class)
478 .child(VtepConfigSchema.class, new VtepConfigSchemaKey(schemaName)).build();
481 public static InstanceIdentifier<VtepConfigSchema> getVtepConfigSchemaIdentifier() {
482 return InstanceIdentifier.builder(VtepConfigSchemas.class).child(VtepConfigSchema.class).build();
485 public static InstanceIdentifier<VtepConfigSchemas> getVtepConfigSchemasIdentifier() {
486 return InstanceIdentifier.builder(VtepConfigSchemas.class).build();
489 public static InstanceIdentifier<VtepIpPool> getVtepIpPoolIdentifier(String subnetCidr) {
490 return InstanceIdentifier.builder(VtepIpPools.class).child(VtepIpPool.class, new VtepIpPoolKey(subnetCidr))
494 public static VtepConfigSchema validateForAddVtepConfigSchema(VtepConfigSchema schema,
495 List<VtepConfigSchema> existingSchemas) {
496 VtepConfigSchema validSchema = validateVtepConfigSchema(schema);
497 for (VtepConfigSchema existingSchema : emptyIfNull(existingSchemas)) {
498 if (!StringUtils.equalsIgnoreCase(schema.getSchemaName(), existingSchema.getSchemaName())
499 && schema.getSubnet().equals(existingSchema.getSubnet())) {
500 String subnetCidr = getSubnetCidrAsString(schema.getSubnet());
501 Preconditions.checkArgument(false, "VTEP schema with subnet [" + subnetCidr
502 + "] already exists. Multiple VTEP schemas with same subnet is not allowed.");
505 if (isNotEmpty(getDpnIdList(validSchema.getDpnIds()))) {
506 String tzone = validSchema.getTransportZoneName();
507 List<BigInteger> lstDpns = getConflictingDpnsAlreadyConfiguredWithTz(validSchema.getSchemaName(), tzone,
508 getDpnIdList(validSchema.getDpnIds()), existingSchemas);
509 if (!lstDpns.isEmpty()) {
510 Preconditions.checkArgument(false, "DPN's " + lstDpns + " already configured for transport zone "
511 + tzone + ". Only one end point per transport Zone per Dpn is allowed.");
513 if (schema.getTunnelType().equals(TunnelTypeGre.class)) {
514 validateForSingleGreTep(validSchema.getSchemaName(), getDpnIdList(validSchema.getDpnIds()),
521 private static void validateForSingleGreTep(String schemaName, List<BigInteger> lstDpnsForAdd,
522 List<VtepConfigSchema> existingSchemas) {
523 for (VtepConfigSchema existingSchema : emptyIfNull(existingSchemas)) {
524 if (TunnelTypeGre.class.equals(existingSchema.getTunnelType())
525 && !StringUtils.equalsIgnoreCase(schemaName, existingSchema.getSchemaName())) {
526 List<BigInteger> lstConflictingDpns = new ArrayList<>(getDpnIdList(existingSchema.getDpnIds()));
527 lstConflictingDpns.retainAll(emptyIfNull(lstDpnsForAdd));
528 if (!lstConflictingDpns.isEmpty()) {
529 String errMsg = "DPN's " + lstConflictingDpns
530 + " already configured with GRE TEP. Mutiple GRE TEP's on a single DPN are not allowed.";
531 Preconditions.checkArgument(false, errMsg);
537 public static VtepConfigSchema validateVtepConfigSchema(VtepConfigSchema schema) {
538 Preconditions.checkNotNull(schema);
539 Preconditions.checkArgument(StringUtils.isNotBlank(schema.getSchemaName()));
540 Preconditions.checkArgument(StringUtils.isNotBlank(schema.getPortName()));
541 Preconditions.checkArgument(schema.getVlanId() >= 0 && schema.getVlanId() < 4095,
542 "Invalid VLAN ID, range (0-4094)");
543 Preconditions.checkArgument(StringUtils.isNotBlank(schema.getTransportZoneName()));
544 Preconditions.checkNotNull(schema.getSubnet());
545 String subnetCidr = getSubnetCidrAsString(schema.getSubnet());
546 SubnetUtils subnetUtils = new SubnetUtils(subnetCidr);
547 IpAddress gatewayIp = schema.getGatewayIp();
548 if (gatewayIp != null) {
549 String strGatewayIp = String.valueOf(gatewayIp.getValue());
550 if (!strGatewayIp.equals(ITMConstants.DUMMY_IP_ADDRESS) && !subnetUtils.getInfo().isInRange(strGatewayIp)) {
551 Preconditions.checkArgument(false, "Gateway IP address " + strGatewayIp
552 + " is not in subnet range " + subnetCidr);
555 ItmUtils.getExcludeIpAddresses(schema.getExcludeIpFilter(), subnetUtils.getInfo());
556 return new VtepConfigSchemaBuilder(schema).setTunnelType(schema.getTunnelType()).build();
559 public static String validateTunnelType(String tunnelType) {
560 if (tunnelType == null) {
561 tunnelType = ITMConstants.TUNNEL_TYPE_VXLAN;
563 tunnelType = StringUtils.upperCase(tunnelType);
564 String error = "Invalid tunnel type. Valid values: "
565 + ITMConstants.TUNNEL_TYPE_VXLAN + " | " + ITMConstants.TUNNEL_TYPE_GRE;
566 Preconditions.checkArgument(ITMConstants.TUNNEL_TYPE_VXLAN.equals(tunnelType)
567 || ITMConstants.TUNNEL_TYPE_GRE.equals(tunnelType), error);
572 private static List<BigInteger> getConflictingDpnsAlreadyConfiguredWithTz(String schemaName, String tzone,
573 List<BigInteger> lstDpns,
574 List<VtepConfigSchema> existingSchemas) {
575 List<BigInteger> lstConflictingDpns = new ArrayList<>();
576 for (VtepConfigSchema schema : emptyIfNull(existingSchemas)) {
577 if (!StringUtils.equalsIgnoreCase(schemaName, schema.getSchemaName())
578 && StringUtils.equals(schema.getTransportZoneName(), tzone)) {
579 lstConflictingDpns = new ArrayList<>(getDpnIdList(schema.getDpnIds()));
580 lstConflictingDpns.retainAll(lstDpns);
581 if (!lstConflictingDpns.isEmpty()) {
586 return lstConflictingDpns;
589 public static VtepConfigSchema constructVtepConfigSchema(String schemaName, String portName, Integer vlanId,
590 String subnetMask, String gatewayIp, String transportZone,
591 String tunnelType, List<BigInteger> dpnIds,
592 String excludeIpFilter) {
593 IpAddress gatewayIpObj = StringUtils.isBlank(gatewayIp) ? null : IpAddressBuilder.getDefaultInstance(gatewayIp);
594 IpPrefix subnet = StringUtils.isBlank(subnetMask) ? null : IpPrefixBuilder.getDefaultInstance(subnetMask);
595 Class<? extends TunnelTypeBase> tunType ;
596 if (tunnelType.equals(ITMConstants.TUNNEL_TYPE_VXLAN)) {
597 tunType = TunnelTypeVxlan.class ;
599 tunType = TunnelTypeGre.class ;
601 VtepConfigSchemaBuilder schemaBuilder = new VtepConfigSchemaBuilder().setSchemaName(schemaName)
602 .setPortName(portName).setVlanId(vlanId).setSubnet(subnet).setGatewayIp(gatewayIpObj)
603 .setTransportZoneName(transportZone).setTunnelType(tunType).setDpnIds(getDpnIdsListFromBigInt(dpnIds))
604 .setExcludeIpFilter(excludeIpFilter);
605 return schemaBuilder.build();
608 public static List<IpAddress> getExcludeIpAddresses(String excludeIpFilter, SubnetInfo subnetInfo) {
609 final List<IpAddress> lstIpAddress = new ArrayList<>();
610 if (StringUtils.isBlank(excludeIpFilter)) {
613 final String[] arrIps = StringUtils.split(excludeIpFilter, ',');
614 for (String ip : arrIps) {
615 if (StringUtils.countMatches(ip, "-") == 1) {
616 final String[] arrIpRange = StringUtils.split(ip, '-');
617 String strStartIp = StringUtils.trim(arrIpRange[0]);
618 String strEndIp = StringUtils.trim(arrIpRange[1]);
619 Preconditions.checkArgument(InetAddresses.isInetAddress(strStartIp),
620 "Invalid exclude IP filter: invalid IP address value " + strStartIp);
621 Preconditions.checkArgument(InetAddresses.isInetAddress(strEndIp),
622 "Invalid exclude IP filter: invalid IP address value " + strEndIp);
623 Preconditions.checkArgument(subnetInfo.isInRange(strStartIp),
624 "Invalid exclude IP filter: IP address [" + strStartIp
625 + "] not in subnet range " + subnetInfo.getCidrSignature());
626 Preconditions.checkArgument(subnetInfo.isInRange(strEndIp),
627 "Invalid exclude IP filter: IP address [" + strEndIp
628 + "] not in subnet range " + subnetInfo.getCidrSignature());
629 int startIp = subnetInfo.asInteger(strStartIp);
630 int endIp = subnetInfo.asInteger(strEndIp);
632 Preconditions.checkArgument(startIp < endIp,
633 "Invalid exclude IP filter: Invalid range [" + ip + "] ");
634 for (int iter = startIp; iter <= endIp; iter++) {
635 String ipAddress = ipFormat(toIpArray(iter));
636 validateAndAddIpAddressToList(subnetInfo, lstIpAddress, ipAddress);
639 validateAndAddIpAddressToList(subnetInfo, lstIpAddress, ip);
645 private static void validateAndAddIpAddressToList(SubnetInfo subnetInfo, final List<IpAddress> lstIpAddress,
647 String ip = StringUtils.trim(ipAddress);
648 Preconditions.checkArgument(InetAddresses.isInetAddress(ip),
649 "Invalid exclude IP filter: invalid IP address value " + ip);
650 Preconditions.checkArgument(subnetInfo.isInRange(ip),
651 "Invalid exclude IP filter: IP address [" + ip + "] not in subnet range "
652 + subnetInfo.getCidrSignature());
653 lstIpAddress.add(IpAddressBuilder.getDefaultInstance(ip));
656 private static int[] toIpArray(int val) {
657 int[] ret = new int[4];
658 for (int iter = 3; iter >= 0; --iter) {
659 ret[iter] |= val >>> 8 * (3 - iter) & 0xff;
664 private static String ipFormat(int[] octets) {
665 StringBuilder str = new StringBuilder();
666 for (int iter = 0; iter < octets.length; ++iter) {
667 str.append(octets[iter]);
668 if (iter != octets.length - 1) {
672 return str.toString();
675 public static VtepConfigSchema validateForUpdateVtepSchema(String schemaName, List<BigInteger> lstDpnsForAdd,
676 List<BigInteger> lstDpnsForDelete,
677 IITMProvider itmProvider) {
678 Preconditions.checkArgument(StringUtils.isNotBlank(schemaName));
679 if ((lstDpnsForAdd == null || lstDpnsForAdd.isEmpty())
680 && (lstDpnsForDelete == null || lstDpnsForDelete.isEmpty())) {
681 Preconditions.checkArgument(false,
682 "DPN ID list for add | delete is null or empty in schema " + schemaName);
684 VtepConfigSchema schema = itmProvider.getVtepConfigSchema(schemaName);
685 if (schema == null) {
686 Preconditions.checkArgument(false, "Specified VTEP Schema [" + schemaName
687 + "] doesn't exists!");
689 List<BigInteger> existingDpnIds = getDpnIdList(schema.getDpnIds());
690 if (isNotEmpty(lstDpnsForAdd)) {
691 List<BigInteger> lstAlreadyExistingDpns = new ArrayList<>(existingDpnIds);
692 lstAlreadyExistingDpns.retainAll(lstDpnsForAdd);
693 Preconditions.checkArgument(lstAlreadyExistingDpns.isEmpty(),
694 "DPN ID's " + lstAlreadyExistingDpns
695 + " already exists in VTEP schema [" + schemaName + "]");
696 if (schema.getTunnelType().equals(TunnelTypeGre.class)) {
697 validateForSingleGreTep(schema.getSchemaName(), lstDpnsForAdd, itmProvider.getAllVtepConfigSchemas());
700 if (isNotEmpty(lstDpnsForDelete)) {
701 if (existingDpnIds.isEmpty()) {
702 String builder = "DPN ID's " + lstDpnsForDelete
703 + " specified for delete from VTEP schema [" + schemaName
704 + "] are not configured in the schema.";
705 Preconditions.checkArgument(false, builder);
706 } else if (!existingDpnIds.containsAll(lstDpnsForDelete)) {
707 List<BigInteger> lstConflictingDpns = new ArrayList<>(lstDpnsForDelete);
708 lstConflictingDpns.removeAll(existingDpnIds);
709 String builder = "DPN ID's " + lstConflictingDpns
710 + " specified for delete from VTEP schema [" + schemaName
711 + "] are not configured in the schema.";
712 Preconditions.checkArgument(false, builder);
718 public static String getSubnetCidrAsString(IpPrefix subnet) {
719 return subnet == null ? StringUtils.EMPTY : String.valueOf(subnet.getValue());
722 public static <T> List<T> emptyIfNull(List<T> list) {
723 return list == null ? Collections.emptyList() : list;
726 public static <T> boolean isEmpty(Collection<T> collection) {
727 return collection == null || collection.isEmpty();
730 public static <T> boolean isNotEmpty(Collection<T> collection) {
731 return !isEmpty(collection);
735 public static HwVtep createHwVtepObject(String topoId, String nodeId, IpAddress ipAddress, IpPrefix ipPrefix,
736 IpAddress gatewayIP, int vlanID,
737 Class<? extends TunnelTypeBase> tunneltype, TransportZone transportZone) {
738 HwVtep hwVtep = new HwVtep();
739 hwVtep.setGatewayIP(gatewayIP);
740 hwVtep.setHwIp(ipAddress);
741 hwVtep.setIpPrefix(ipPrefix);
742 hwVtep.setNodeId(nodeId);
743 hwVtep.setTopoId(topoId);
744 hwVtep.setTransportZone(transportZone.getZoneName());
745 hwVtep.setTunnelType(tunneltype);
746 hwVtep.setVlanID(vlanID);
750 public static String getHwParentIf(String topoId, String srcNodeid) {
751 return String.format("%s:%s", topoId, srcNodeid);
754 public static <T extends DataObject> void syncWrite(LogicalDatastoreType datastoreType,
755 InstanceIdentifier<T> path, T data, DataBroker broker) {
756 WriteTransaction tx = broker.newWriteOnlyTransaction();
757 tx.put(datastoreType, path, data, true);
760 } catch (InterruptedException | ExecutionException e) {
761 LOG.error("ITMUtils:SyncWrite , Error writing to datastore (path, data) : ({}, {})", path, data);
762 throw new RuntimeException(e.getMessage(), e);
767 public static List<BigInteger> getDpnIdList(List<DpnIds> dpnIds) {
768 List<BigInteger> dpnList = new ArrayList<>() ;
769 for (DpnIds dpn : dpnIds) {
770 dpnList.add(dpn.getDPN()) ;
775 public static List<DpnIds> getDpnIdsListFromBigInt(List<BigInteger> dpnIds) {
776 List<DpnIds> dpnIdList = new ArrayList<>();
777 DpnIdsBuilder builder = new DpnIdsBuilder();
778 for (BigInteger dpnId : dpnIds) {
779 dpnIdList.add(builder.setKey(new DpnIdsKey(dpnId)).setDPN(dpnId).build());
784 public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces
785 .rev140508.interfaces.state.Interface> buildStateInterfaceId(
786 String interfaceName) {
787 return InstanceIdentifier.builder(InterfacesState.class)
788 .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
789 .state.Interface.class,
790 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces
791 .rev140508.interfaces.state.InterfaceKey(
792 interfaceName)).build();
796 public static List<String> getInternalTunnelInterfaces(DataBroker dataBroker) {
797 List<String> tunnelList = new ArrayList<>();
798 Collection<String> internalInterfaces = ITM_CACHE.getAllInternalInterfaces();
799 if (internalInterfaces == null) {
800 updateTunnelsCache(dataBroker);
801 internalInterfaces = ITM_CACHE.getAllInternalInterfaces();
803 LOG.debug("ItmUtils.getTunnelList Cache Internal Interfaces size: {} ", internalInterfaces.size());
804 tunnelList.addAll(internalInterfaces);
805 LOG.trace("ItmUtils.getTunnelList Internal: {}", tunnelList);
809 public static List<String> getTunnelsofTzone(List<HwVtep> hwVteps, String tzone, DataBroker dataBroker,
810 Boolean hwVtepsExist) {
811 List<String> tunnels = new ArrayList<>();
812 InstanceIdentifier<TransportZone> path = InstanceIdentifier.builder(TransportZones.class)
813 .child(TransportZone.class, new TransportZoneKey(tzone)).build();
814 Optional<TransportZone> transportZoneOptional =
815 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
816 if (transportZoneOptional.isPresent()) {
817 TransportZone transportZone = transportZoneOptional.get();
818 Class<? extends TunnelTypeBase> tunType = transportZone.getTunnelType();
819 if (transportZone.getSubnets() != null && !transportZone.getSubnets().isEmpty()) {
820 for (Subnets sub : transportZone.getSubnets()) {
821 if (sub.getVteps() != null && !sub.getVteps().isEmpty()) {
822 for (Vteps vtepLocal : sub.getVteps()) {
823 for (Vteps vtepRemote : sub.getVteps()) {
824 if (!vtepLocal.equals(vtepRemote)) {
825 InternalTunnelKey key = new InternalTunnelKey(vtepRemote.getDpnId(),
826 vtepLocal.getDpnId(), tunType);
827 InstanceIdentifier<InternalTunnel> intIID =
828 InstanceIdentifier.builder(TunnelList.class)
829 .child(InternalTunnel.class, key).build();
830 Optional<InternalTunnel> tunnelsOptional =
831 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, intIID, dataBroker);
832 if (tunnelsOptional.isPresent()) {
833 List<String> tunnelInterfaceNames = tunnelsOptional
834 .get().getTunnelInterfaceNames();
835 if (tunnelInterfaceNames != null && !tunnelInterfaceNames.isEmpty()) {
836 String tunnelInterfaceName = tunnelInterfaceNames.get(0);
837 LOG.trace("Internal Tunnel added {}", tunnelInterfaceName);
838 tunnels.add(tunnelInterfaceName);
843 if (hwVteps != null && !hwVteps.isEmpty()) {
844 for (HwVtep hwVtep : hwVteps) {
845 tunnels.add(getExtTunnel(hwVtep.getNodeId(), vtepLocal.getDpnId().toString(),
846 tunType, dataBroker));
847 tunnels.add(getExtTunnel(vtepLocal.getDpnId().toString(), hwVtep.getNodeId(),
848 tunType, dataBroker));
856 for (HwVtep hwVtep : hwVteps) {
857 for (HwVtep hwVtepOther : hwVteps) {
858 if (!hwVtep.getHwIp().equals(hwVtepOther.getHwIp())) {
859 tunnels.add(getExtTunnel(hwVtep.getNodeId(), hwVtepOther.getNodeId(),
860 tunType, dataBroker));
861 tunnels.add(getExtTunnel(hwVtepOther.getNodeId(), hwVtep.getNodeId(),
862 tunType, dataBroker));
871 public static List<String> getInternalTunnelsofTzone(String tzone, DataBroker dataBroker) {
872 List<String> tunnels = new ArrayList<>();
873 LOG.trace("Getting internal tunnels of {}",tzone);
874 InstanceIdentifier<TransportZone> path = InstanceIdentifier.builder(TransportZones.class)
875 .child(TransportZone.class, new TransportZoneKey(tzone)).build();
876 Optional<TransportZone> transportZoneOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
878 if (transportZoneOptional.isPresent()) {
879 TransportZone transportZone = transportZoneOptional.get();
880 if (transportZone.getSubnets() != null && !transportZone.getSubnets().isEmpty()) {
881 for (Subnets sub : transportZone.getSubnets()) {
882 if (sub.getVteps() != null && !sub.getVteps().isEmpty()) {
883 for (Vteps vtepLocal : sub.getVteps()) {
884 for (Vteps vtepRemote : sub.getVteps()) {
885 if (!vtepLocal.equals(vtepRemote)) {
886 InternalTunnelKey key =
887 new InternalTunnelKey(vtepRemote.getDpnId(), vtepLocal.getDpnId(),
888 transportZone.getTunnelType());
889 InstanceIdentifier<InternalTunnel> intIID =
890 InstanceIdentifier.builder(TunnelList.class)
891 .child(InternalTunnel.class, key).build();
892 Optional<InternalTunnel> tunnelsOptional =
893 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, intIID, dataBroker);
894 if (tunnelsOptional.isPresent()) {
895 List<String> tunnelInterfaceNames = tunnelsOptional.get()
896 .getTunnelInterfaceNames();
897 if (tunnelInterfaceNames != null && !tunnelInterfaceNames.isEmpty()) {
898 String tunnelInterfaceName = tunnelInterfaceNames.get(0);
899 LOG.trace("Internal Tunnel added {}", tunnelInterfaceName);
900 tunnels.add(tunnelInterfaceName);
913 private static String getExtTunnel(String nodeId, String dpId,Class<? extends TunnelTypeBase> tunType, DataBroker
915 LOG.trace("getting ext tunnel for {} and dpId {}",nodeId,dpId);
916 ExternalTunnelKey key = getExternalTunnelKey(dpId, nodeId, tunType);
917 InstanceIdentifier<ExternalTunnel> intIID = InstanceIdentifier.builder(ExternalTunnelList.class)
918 .child(ExternalTunnel.class, key).build();
919 Optional<ExternalTunnel> tunnelsOptional =
920 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, intIID, dataBroker);
921 if (tunnelsOptional.isPresent()) {
922 String tunnelInterfaceName = tunnelsOptional.get().getTunnelInterfaceName();
923 LOG.trace("ext tunnel returned {} ", tunnelInterfaceName);
924 return tunnelInterfaceName;
929 @SuppressFBWarnings("RV_CHECK_FOR_POSITIVE_INDEXOF")
930 public static ExternalTunnelKey getExternalTunnelKey(String dst , String src,
931 Class<? extends TunnelTypeBase> tunType) {
932 final int srcIndex = src.indexOf("physicalswitch");
934 src = src.substring(0, srcIndex - 1);
936 final int dstIndex = dst.indexOf("physicalswitch");
938 dst = dst.substring(0, dstIndex - 1);
940 return new ExternalTunnelKey(dst, src, tunType);
943 public static List<TunnelEndPoints> getTEPsForDpn(BigInteger srcDpn, Collection<DPNTEPsInfo> dpnList) {
944 for (DPNTEPsInfo dpn : dpnList) {
945 if (dpn.getDPNID().equals(srcDpn)) {
946 return dpn.getTunnelEndPoints() ;
952 private static List<InternalTunnel> getAllInternalTunnels(DataBroker dataBroker) {
953 List<InternalTunnel> result = null;
954 InstanceIdentifier<TunnelList> iid = InstanceIdentifier.builder(TunnelList.class).build();
955 Optional<TunnelList> tunnelList = read(LogicalDatastoreType.CONFIGURATION, iid, dataBroker);
956 if (tunnelList.isPresent()) {
957 result = tunnelList.get().getInternalTunnel();
959 if (result == null) {
960 result = Collections.emptyList();
965 public static InternalTunnel getInternalTunnel(String interfaceName, DataBroker broker) {
966 InternalTunnel internalTunnel = ITM_CACHE.getInternalTunnel(interfaceName);
967 if (internalTunnel == null) {
968 updateTunnelsCache(broker);
969 internalTunnel = ITM_CACHE.getInternalTunnel(interfaceName);
971 return internalTunnel;
974 public static ExternalTunnel getExternalTunnel(String interfaceName, DataBroker broker) {
975 ExternalTunnel externalTunnel = ITM_CACHE.getExternalTunnel(interfaceName);
976 if (externalTunnel == null) {
977 updateTunnelsCache(broker);
978 externalTunnel = ITM_CACHE.getExternalTunnel(interfaceName);
980 return externalTunnel;
983 private static List<ExternalTunnel> getAllExternalTunnels(DataBroker dataBroker) {
984 List<ExternalTunnel> result = null;
985 InstanceIdentifier<ExternalTunnelList> iid = InstanceIdentifier.builder(ExternalTunnelList.class).build();
986 Optional<ExternalTunnelList> tunnelList = read(LogicalDatastoreType.CONFIGURATION, iid, dataBroker);
987 if (tunnelList.isPresent()) {
988 result = tunnelList.get().getExternalTunnel();
990 if (result == null) {
991 result = Collections.emptyList();
996 public static String convertTunnelTypetoString(Class<? extends TunnelTypeBase> tunType) {
997 String tunnelType = ITMConstants.TUNNEL_TYPE_VXLAN;
998 if (tunType.equals(TunnelTypeVxlan.class)) {
999 tunnelType = ITMConstants.TUNNEL_TYPE_VXLAN ;
1000 } else if (tunType.equals(TunnelTypeGre.class)) {
1001 tunnelType = ITMConstants.TUNNEL_TYPE_GRE ;
1002 } else if (tunType.equals(TunnelTypeMplsOverGre.class)) {
1003 tunnelType = ITMConstants.TUNNEL_TYPE_MPLSoGRE;
1004 } else if (tunType.equals(TunnelTypeLogicalGroup.class)) {
1005 tunnelType = ITMConstants.TUNNEL_TYPE_LOGICAL_GROUP_VXLAN;
1011 public static boolean isItmIfType(Class<? extends InterfaceType> ifType) {
1012 return ifType != null && ifType.isAssignableFrom(Tunnel.class);
1015 public static StateTunnelListKey getTunnelStateKey(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
1016 .interfaces.rev140508.interfaces.state.Interface iface) {
1017 StateTunnelListKey key = null;
1018 if (isItmIfType(iface.getType())) {
1019 key = new StateTunnelListKey(iface.getName());
1024 private static void updateTunnelsCache(DataBroker broker) {
1025 List<InternalTunnel> internalTunnels = getAllInternalTunnels(broker);
1026 for (InternalTunnel tunnel : internalTunnels) {
1027 ITM_CACHE.addInternalTunnel(tunnel);
1029 List<ExternalTunnel> externalTunnels = getAllExternalTunnels(broker);
1030 for (ExternalTunnel tunnel : externalTunnels) {
1031 ITM_CACHE.addExternalTunnel(tunnel);
1035 public static Interface getInterface(
1036 String name, IInterfaceManager ifaceManager) {
1037 Interface result = ITM_CACHE.getInterface(name);
1038 if (result == null) {
1039 result = ifaceManager.getInterfaceInfoFromConfigDataStore(name);
1040 if (result != null) {
1041 ITM_CACHE.addInterface(result);
1047 public static List<DcGatewayIp> getDcGatewayIpList(DataBroker broker) {
1048 InstanceIdentifier<DcGatewayIpList> dcGatewayIpListid =
1049 InstanceIdentifier.builder(DcGatewayIpList.class).build();
1050 Optional<DcGatewayIpList> dcGatewayIpListConfig =
1051 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, dcGatewayIpListid, broker);
1052 if (dcGatewayIpListConfig.isPresent()) {
1053 DcGatewayIpList containerList = dcGatewayIpListConfig.get();
1054 if (containerList != null) {
1055 return containerList.getDcGatewayIp();
1061 public static boolean falseIfNull(Boolean value) {
1062 return value == null ? false : value;
1065 public static <T> List<T> getIntersection(List<T> list1, List<T> list2) {
1066 List<T> list = new ArrayList<>();
1067 for (T iter : list1) {
1068 if (list2.contains(iter)) {
1072 LOG.debug(" getIntersection - L1 {}, L2 - {}, Intersection - {}", list1, list2, list);
1076 public static void addTransportZoneMembership(List<TzMembership> zones, String zoneName) {
1077 zones.add(new TzMembershipBuilder().setZoneName(zoneName).build());
1080 public static List<TzMembership> createTransportZoneMembership(String zoneName) {
1081 List<TzMembership> zones = new ArrayList<>();
1082 zones.add(new TzMembershipBuilder().setZoneName(zoneName).build());
1087 * Gets the transport zone in TepsNotHosted list in the Configuration Datastore, based on transport zone name.
1089 * @param unknownTz transport zone name
1091 * @param dataBroker data broker handle to perform read operations on config datastore
1093 * @return the TepsNotHostedInTransportZone object in the TepsNotHosted list in Config DS
1095 public static TepsNotHostedInTransportZone getUnknownTransportZoneFromITMConfigDS(
1096 String unknownTz, DataBroker dataBroker) {
1097 InstanceIdentifier<TepsNotHostedInTransportZone> unknownTzPath =
1098 InstanceIdentifier.builder(TransportZones.class)
1099 .child(TepsNotHostedInTransportZone.class,
1100 new TepsNotHostedInTransportZoneKey(unknownTz)).build();
1101 Optional<TepsNotHostedInTransportZone> unknownTzOptional =
1102 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, unknownTzPath, dataBroker);
1103 if (unknownTzOptional.isPresent()) {
1104 return unknownTzOptional.get();
1110 * Gets the bridge datapath ID from Network topology Node's OvsdbBridgeAugmentation, in the Operational DS.
1112 * @param node Network Topology Node
1114 * @param bridge bridge name
1116 * @param dataBroker data broker handle to perform operations on datastore
1118 * @return the datapath ID of bridge in string form
1120 public static String getBridgeDpid(Node node, String bridge, DataBroker dataBroker) {
1121 OvsdbBridgeAugmentation ovsdbBridgeAugmentation = null;
1122 Node bridgeNode = null;
1123 String datapathId = null;
1125 NodeId ovsdbNodeId = node.getKey().getNodeId();
1127 NodeId brNodeId = new NodeId(ovsdbNodeId.getValue()
1128 + "/" + ITMConstants.BRIDGE_URI_PREFIX + "/" + bridge);
1130 InstanceIdentifier<Node> bridgeIid =
1132 .create(NetworkTopology.class)
1133 .child(Topology.class, new TopologyKey(IfmConstants.OVSDB_TOPOLOGY_ID))
1134 .child(Node.class,new NodeKey(brNodeId));
1136 Optional<Node> opBridgeNode = ItmUtils.read(LogicalDatastoreType.OPERATIONAL, bridgeIid, dataBroker);
1138 if (opBridgeNode.isPresent()) {
1139 bridgeNode = opBridgeNode.get();
1141 if (bridgeNode != null) {
1142 ovsdbBridgeAugmentation = bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class);
1145 if (ovsdbBridgeAugmentation != null && ovsdbBridgeAugmentation.getDatapathId() != null) {
1146 datapathId = ovsdbBridgeAugmentation.getDatapathId().getValue();
1152 * Gets the Network topology Node from Operational Datastore
1153 * based on Bridge Augmentation.
1155 * @param bridgeAugmentation bridge augmentation of OVSDB node
1157 * @param dataBroker data broker handle to perform operations on datastore
1159 * @return the Network Topology Node i.e. OVSDB node which is managing the specified bridge
1161 public static Node getOvsdbNode(OvsdbBridgeAugmentation bridgeAugmentation,
1162 DataBroker dataBroker) {
1163 Node ovsdbNode = null;
1164 Optional<Node> opOvsdbNode = Optional.absent();
1165 if (bridgeAugmentation != null) {
1166 InstanceIdentifier<Node> ovsdbNodeIid =
1167 (InstanceIdentifier<Node>) bridgeAugmentation.getManagedBy().getValue();
1168 opOvsdbNode = ItmUtils.read(LogicalDatastoreType.OPERATIONAL, ovsdbNodeIid, dataBroker);
1170 if (opOvsdbNode.isPresent()) {
1171 ovsdbNode = opOvsdbNode.get();
1177 * Gets the bridge datapath ID in string form from
1178 * Network topology Node's OvsdbBridgeAugmentation in the Operational DS.
1180 * @param augmentedNode Ovsdb Augmented Network Topology Node
1182 * @return the datapath ID of bridge in string form
1184 public static String getStrDatapathId(OvsdbBridgeAugmentation augmentedNode) {
1185 String datapathId = null;
1186 if (augmentedNode != null && augmentedNode.getDatapathId() != null) {
1187 datapathId = augmentedNode.getDatapathId().getValue();
1193 * Returns the dummy subnet (255.255.255.255/32) as IpPrefix object.
1195 * @return the dummy subnet (255.255.255.255/32) in IpPrefix object
1197 public static IpPrefix getDummySubnet() {
1198 return DUMMY_IP_PREFIX;
1202 * Deletes the transport zone from Configuration datastore.
1204 * @param tzName transport zone name
1205 * @param dataBroker data broker handle to perform operations on datastore
1207 public static void deleteTransportZoneFromConfigDS(String tzName, DataBroker dataBroker) {
1208 // check whether transport-zone exists in config DS.
1209 TransportZone transportZoneFromConfigDS = ItmUtils.getTransportZoneFromConfigDS(tzName, dataBroker);
1210 if (transportZoneFromConfigDS != null) {
1211 // it exists, delete default-TZ now
1212 InstanceIdentifier<TransportZone> path = InstanceIdentifier.builder(TransportZones.class)
1213 .child(TransportZone.class, new TransportZoneKey(tzName)).build();
1214 LOG.debug("Removing {} transport-zone from config DS.", tzName);
1216 SingleTransactionDataBroker.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, path);
1217 } catch (TransactionCommitFailedException e) {
1218 LOG.error("deleteTransportZoneFromConfigDS failed. {} could not be deleted.", tzName, e);
1224 * Validates the tunnelType argument and returnsTunnelTypeBase class object
1225 * corresponding to tunnelType obtained in String format.
1227 * @param tunnelType type of tunnel in string form
1229 * @return tunnel-type in TunnelTypeBase object
1231 public static Class<? extends TunnelTypeBase> getTunnelType(String tunnelType) {
1232 // validate tunnelType string, in case it is NULL or empty, then
1233 // take VXLAN tunnel type by default
1234 if (tunnelType == null || tunnelType.isEmpty()) {
1235 return TUNNEL_TYPE_MAP.get(ITMConstants.TUNNEL_TYPE_VXLAN);
1236 } else if (!tunnelType.equals(ITMConstants.TUNNEL_TYPE_VXLAN)
1237 && !tunnelType.equals(ITMConstants.TUNNEL_TYPE_GRE)) {
1238 // if tunnel type is some incorrect value, then
1239 // take VXLAN tunnel type by default
1240 return TUNNEL_TYPE_MAP.get(ITMConstants.TUNNEL_TYPE_VXLAN);
1243 // return TunnelTypeBase object corresponding to tunnel-type
1244 return TUNNEL_TYPE_MAP.get(tunnelType);
1247 public static List<TzMembership> removeTransportZoneMembership(TunnelEndPoints endPts, List<TzMembership> zones) {
1248 LOG.trace(" RemoveTransportZoneMembership TEPs {}, Membership to be removed {} ", endPts, zones);
1249 List<TzMembership> existingTzList = new ArrayList<>(endPts.getTzMembership()) ;
1250 for (TzMembership membership : zones) {
1251 existingTzList.remove(new TzMembershipBuilder().setZoneName(membership.getZoneName()).build());
1253 LOG.debug("Modified Membership List {}", existingTzList);
1254 return existingTzList;
1257 public static List<TzMembership> getOriginalTzMembership(TunnelEndPoints srcTep, BigInteger dpnId,
1258 Collection<DPNTEPsInfo> meshedDpnList) {
1259 LOG.trace("Original Membership for source DPN {}, source TEP {}", dpnId, srcTep);
1260 for (DPNTEPsInfo dstDpn : meshedDpnList) {
1261 if (dpnId.equals(dstDpn.getDPNID())) {
1262 List<TunnelEndPoints> endPts = dstDpn.getTunnelEndPoints();
1263 for (TunnelEndPoints tep : endPts) {
1264 if (tep.getIpAddress().equals(srcTep.getIpAddress())) {
1265 LOG.debug("Original Membership size {}", tep.getTzMembership().size()) ;
1266 return tep.getTzMembership();
1274 public static StateTunnelList buildStateTunnelList(StateTunnelListKey tlKey, String name, boolean state,
1275 TunnelOperStatus tunOpStatus, IInterfaceManager ifaceManager,
1276 DataBroker broker) {
1277 StateTunnelListBuilder stlBuilder = new StateTunnelListBuilder();
1278 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface =
1279 ItmUtils.getInterface(name, ifaceManager);
1280 IfTunnel ifTunnel = iface.getAugmentation(IfTunnel.class);
1281 ParentRefs parentRefs = iface.getAugmentation(ParentRefs.class);
1282 if (ifTunnel == null || parentRefs == null) {
1285 DstInfoBuilder dstInfoBuilder = new DstInfoBuilder();
1286 SrcInfoBuilder srcInfoBuilder = new SrcInfoBuilder();
1287 dstInfoBuilder.setTepIp(ifTunnel.getTunnelDestination());
1288 srcInfoBuilder.setTepIp(ifTunnel.getTunnelSource());
1289 // TODO: Add/Improve logic for device type
1290 InternalTunnel internalTunnel = ItmUtils.ITM_CACHE.getInternalTunnel(name);
1291 ExternalTunnel externalTunnel = ItmUtils.ITM_CACHE.getExternalTunnel(name);
1292 if (internalTunnel == null && externalTunnel == null) {
1293 // both not present in cache. let us update and try again.
1294 ItmUtils.updateTunnelsCache(broker);
1295 internalTunnel = ItmUtils.ITM_CACHE.getInternalTunnel(name);
1296 externalTunnel = ItmUtils.ITM_CACHE.getExternalTunnel(name);
1298 if (internalTunnel != null) {
1299 srcInfoBuilder.setTepDeviceId(internalTunnel.getSourceDPN().toString())
1300 .setTepDeviceType(TepTypeInternal.class);
1301 dstInfoBuilder.setTepDeviceId(internalTunnel.getDestinationDPN().toString())
1302 .setTepDeviceType(TepTypeInternal.class);
1303 stlBuilder.setTransportType(internalTunnel.getTransportType());
1304 } else if (externalTunnel != null) {
1305 ExternalTunnel tunnel = ItmUtils.ITM_CACHE.getExternalTunnel(name);
1306 srcInfoBuilder.setTepDeviceId(tunnel.getSourceDevice())
1307 .setTepDeviceType(getDeviceType(tunnel.getSourceDevice()));
1308 dstInfoBuilder.setTepDeviceId(tunnel.getDestinationDevice())
1309 .setTepDeviceType(getDeviceType(tunnel.getDestinationDevice()))
1310 .setTepIp(ifTunnel.getTunnelDestination());
1311 stlBuilder.setTransportType(tunnel.getTransportType());
1313 stlBuilder.setKey(tlKey).setTunnelInterfaceName(name).setOperState(tunOpStatus).setTunnelState(state)
1314 .setDstInfo(dstInfoBuilder.build()).setSrcInfo(srcInfoBuilder.build());
1315 return stlBuilder.build();
1318 private static Class<? extends TepTypeBase> getDeviceType(String device) {
1319 if (device.startsWith("hwvtep")) {
1320 return TepTypeHwvtep.class;
1321 } else if (device.contains("IpAddress")) {
1322 return TepTypeExternal.class;
1324 return TepTypeInternal.class;
1328 public static InstanceIdentifier<StateTunnelList> buildStateTunnelListId(StateTunnelListKey tlKey) {
1329 return InstanceIdentifier.builder(TunnelsState.class)
1330 .child(StateTunnelList.class, tlKey).build();
1334 public static Optional<InternalTunnel> getInternalTunnelFromDS(BigInteger srcDpn, BigInteger destDpn,
1335 Class<? extends TunnelTypeBase> type,
1336 DataBroker dataBroker) {
1337 InstanceIdentifier<InternalTunnel> pathLogicTunnel = InstanceIdentifier.create(TunnelList.class)
1338 .child(InternalTunnel.class,
1339 new InternalTunnelKey(destDpn, srcDpn, type));
1340 //TODO: need to be replaced by cached copy
1341 return ItmUtils.read(LogicalDatastoreType.CONFIGURATION, pathLogicTunnel, dataBroker);
1344 public static boolean isTunnelAggregationUsed(Class<? extends TunnelTypeBase> tunType) {
1345 return ItmTunnelAggregationHelper.isTunnelAggregationEnabled()
1346 && (tunType.isAssignableFrom(TunnelTypeVxlan.class)
1347 || tunType.isAssignableFrom(TunnelTypeLogicalGroup.class));
1350 public static List<TunnelOptions> buildTunnelOptions(TunnelEndPoints tep, ItmConfig itmConfig) {
1351 List<TunnelOptions> tunOptions = new ArrayList<>();
1353 String tos = tep.getOptionTunnelTos();
1355 tos = itmConfig.getDefaultTunnelTos();
1357 /* populate tos option only if its not default value of 0 */
1358 if (tos != null && !tos.equals("0")) {
1359 TunnelOptionsBuilder optionsBuilder = new TunnelOptionsBuilder();
1360 optionsBuilder.setKey(new TunnelOptionsKey("tos"));
1361 optionsBuilder.setTunnelOption("tos");
1362 optionsBuilder.setValue(tos);
1363 tunOptions.add(optionsBuilder.build());
1366 if (tep.getTunnelType() == TunnelTypeVxlan.class && itmConfig.isGpeExtensionEnabled()) {
1367 TunnelOptionsBuilder optionsBuilder = new TunnelOptionsBuilder();
1368 optionsBuilder.setKey(new TunnelOptionsKey("exts"));
1369 optionsBuilder.setTunnelOption("exts");
1370 optionsBuilder.setValue("gpe");
1371 tunOptions.add(optionsBuilder.build());
1373 return tunOptions.isEmpty() ? null : tunOptions;
1376 public static ExternalTunnel getExternalTunnelbyExternalTunnelKey(ExternalTunnelKey externalTunnelKey,
1377 InstanceIdentifier<ExternalTunnel> path,
1378 DataBroker dataBroker) {
1379 ExternalTunnel exTunnel = ITM_CACHE.getExternalTunnelKeyToExternalTunnels().get(externalTunnelKey);
1380 if (exTunnel == null) {
1381 Optional<ExternalTunnel> ext = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
1382 if (ext.isPresent()) {
1383 exTunnel = ext.get();
1389 public static List<DPNTEPsInfo> getDpnTEPsInfos(DataBroker dataBroker) {
1390 InstanceIdentifier<DpnEndpoints> iid = InstanceIdentifier.builder(DpnEndpoints.class).build();
1391 Optional<DpnEndpoints> dpnEndpoints = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, iid, dataBroker);
1392 if (dpnEndpoints.isPresent()) {
1393 return dpnEndpoints.get().getDPNTEPsInfo();
1395 return new ArrayList<>();
1399 public static InstanceIdentifier<TransportZone> getTZInstanceIdentifier(String tzName) {
1400 return InstanceIdentifier.builder(TransportZones.class).child(TransportZone.class,
1401 new TransportZoneKey(tzName)).build();
1405 * Returns the transport zone from Configuration datastore.
1407 * @param tzName transport zone name
1408 * @param dataBroker data broker handle to perform operations on datastore
1409 * @return the TransportZone object in Config DS
1411 // FIXME: Better is to implement cache to avoid datastore read.
1412 public static TransportZone getTransportZoneFromConfigDS(String tzName, DataBroker dataBroker) {
1413 InstanceIdentifier<TransportZone> tzonePath = getTZInstanceIdentifier(tzName);
1414 Optional<TransportZone> transportZoneOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, tzonePath,
1416 if (transportZoneOptional.isPresent()) {
1417 return transportZoneOptional.get();
1422 public static Class<? extends TunnelTypeBase> convertStringToTunnelType(String tunnelType) {
1423 Class<? extends TunnelTypeBase> tunType = TunnelTypeVxlan.class;
1424 if (STRING_CLASS_IMMUTABLE_BI_MAP.containsKey(tunnelType)) {
1425 tunType = STRING_CLASS_IMMUTABLE_BI_MAP.get(tunnelType);