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.ImmutableMap;
13 import com.google.common.net.InetAddresses;
14 import com.google.common.util.concurrent.CheckedFuture;
15 import com.google.common.util.concurrent.FutureCallback;
16 import com.google.common.util.concurrent.Futures;
17 import java.math.BigInteger;
18 import java.net.InetAddress;
19 import java.util.ArrayList;
20 import java.util.Collection;
21 import java.util.Collections;
22 import java.util.List;
23 import java.util.UUID;
24 import java.util.concurrent.ExecutionException;
25 import java.util.concurrent.Future;
27 import org.apache.commons.lang3.StringUtils;
28 import org.apache.commons.net.util.SubnetUtils;
29 import org.apache.commons.net.util.SubnetUtils.SubnetInfo;
30 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
31 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
32 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
33 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
34 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
35 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
36 import org.opendaylight.genius.interfacemanager.globals.IfmConstants;
37 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
38 import org.opendaylight.genius.itm.api.IITMProvider;
39 import org.opendaylight.genius.itm.confighelpers.HwVtep;
40 import org.opendaylight.genius.itm.confighelpers.ItmTunnelAggregationHelper;
41 import org.opendaylight.genius.itm.globals.ITMConstants;
42 import org.opendaylight.genius.mdsalutil.ActionInfo;
43 import org.opendaylight.genius.mdsalutil.FlowEntity;
44 import org.opendaylight.genius.mdsalutil.InstructionInfo;
45 import org.opendaylight.genius.mdsalutil.MDSALUtil;
46 import org.opendaylight.genius.mdsalutil.MatchInfo;
47 import org.opendaylight.genius.mdsalutil.NwConstants;
48 import org.opendaylight.genius.mdsalutil.actions.ActionPuntToController;
49 import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
50 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
51 import org.opendaylight.genius.mdsalutil.matches.MatchTunnelId;
52 import org.opendaylight.genius.utils.cache.DataStoreCache;
53 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel;
54 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
55 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
56 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType;
57 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
58 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
59 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
60 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
61 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInput;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInputBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlanBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnel;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnelBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefs;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefsBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelMonitoringTypeBase;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelMonitoringTypeBfd;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeGre;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeLogicalGroup;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeMplsOverGre;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.interfaces._interface.NodeIdentifier;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.interfaces._interface.NodeIdentifierBuilder;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.interfaces._interface.NodeIdentifierKey;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.tunnel.optional.params.TunnelOptions;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.tunnel.optional.params.TunnelOptionsBuilder;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.tunnel.optional.params.TunnelOptionsKey;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.ItmConfig;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.TunnelMonitorInterval;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.TunnelMonitorIntervalBuilder;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.TunnelMonitorParams;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.TunnelMonitorParamsBuilder;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.VtepConfigSchemas;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.VtepIpPools;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.VtepConfigSchema;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.VtepConfigSchemaBuilder;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.VtepConfigSchemaKey;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.vtep.config.schema.DpnIds;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.vtep.config.schema.DpnIdsBuilder;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.vtep.config.schema.DpnIdsKey;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.ip.pools.VtepIpPool;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.ip.pools.VtepIpPoolKey;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpointsBuilder;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.ExternalTunnelList;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeBase;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeExternal;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeHwvtep;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeInternal;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelList;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelOperStatus;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelsState;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoBuilder;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoKey;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPointsBuilder;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPointsKey;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.tunnel.end.points.TzMembership;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.tunnel.end.points.TzMembershipBuilder;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnel;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnelBuilder;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnelKey;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnel;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnelBuilder;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnelKey;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelList;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelListBuilder;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelListKey;
129 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.state.tunnel.list.DstInfoBuilder;
130 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.state.tunnel.list.SrcInfoBuilder;
131 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.DcGatewayIpList;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZones;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.dc.gateway.ip.list.DcGatewayIp;
134 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TepsNotHostedInTransportZone;
135 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TepsNotHostedInTransportZoneKey;
136 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZone;
137 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZoneKey;
138 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.Subnets;
139 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.Vteps;
140 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
141 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
142 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
143 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
144 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
145 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
146 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
147 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
148 import org.opendaylight.yangtools.yang.binding.DataObject;
149 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
150 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
151 import org.opendaylight.yangtools.yang.common.RpcResult;
152 import org.slf4j.Logger;
153 import org.slf4j.LoggerFactory;
155 public class ItmUtils {
157 public static final String DUMMY_IP_ADDRESS = "0.0.0.0";
158 public static final String TUNNEL_TYPE_VXLAN = "VXLAN";
159 public static final String TUNNEL_TYPE_GRE = "GRE";
160 public static final String TUNNEL = "tun";
161 public static final IpPrefix DUMMY_IP_PREFIX = new IpPrefix(ITMConstants.DUMMY_PREFIX.toCharArray());
162 public static ItmCache itmCache = new ItmCache();
164 private static final Logger LOG = LoggerFactory.getLogger(ItmUtils.class);
166 public static final ImmutableMap<String, Class<? extends TunnelTypeBase>>
168 new ImmutableMap.Builder<String, Class<? extends TunnelTypeBase>>()
169 .put(ITMConstants.TUNNEL_TYPE_GRE, TunnelTypeGre.class)
170 .put(ITMConstants.TUNNEL_TYPE_MPLSoGRE, TunnelTypeMplsOverGre.class)
171 .put(ITMConstants.TUNNEL_TYPE_VXLAN, TunnelTypeVxlan.class)
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(Throwable error) {
182 LOG.error("Error in Datastore write operation", error);
186 @SuppressWarnings("checkstyle:IllegalCatch")
187 public static <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType,
188 InstanceIdentifier<T> path, DataBroker broker) {
189 try (ReadOnlyTransaction tx = broker.newReadOnlyTransaction()) {
190 return tx.read(datastoreType, path).get();
191 } catch (Exception e) {
192 throw new RuntimeException(e);
196 public static <T extends DataObject> void asyncWrite(LogicalDatastoreType datastoreType,
197 InstanceIdentifier<T> path, T data, DataBroker broker,
198 FutureCallback<Void> callback) {
199 WriteTransaction tx = broker.newWriteOnlyTransaction();
200 tx.put(datastoreType, path, data, true);
201 Futures.addCallback(tx.submit(), callback);
204 public static <T extends DataObject> void asyncUpdate(LogicalDatastoreType datastoreType,
205 InstanceIdentifier<T> path, T data, DataBroker broker,
206 FutureCallback<Void> callback) {
207 WriteTransaction tx = broker.newWriteOnlyTransaction();
208 tx.merge(datastoreType, path, data, true);
209 Futures.addCallback(tx.submit(), callback);
212 public static <T extends DataObject> void asyncDelete(LogicalDatastoreType datastoreType,
213 InstanceIdentifier<T> path, DataBroker broker,
214 FutureCallback<Void> callback) {
215 WriteTransaction tx = broker.newWriteOnlyTransaction();
216 tx.delete(datastoreType, path);
217 Futures.addCallback(tx.submit(), callback);
220 public static <T extends DataObject> void asyncBulkRemove(final DataBroker broker,
221 final LogicalDatastoreType datastoreType,
222 List<InstanceIdentifier<T>> pathList,
223 FutureCallback<Void> callback) {
224 if (!pathList.isEmpty()) {
225 WriteTransaction tx = broker.newWriteOnlyTransaction();
226 for (InstanceIdentifier<T> path : pathList) {
227 tx.delete(datastoreType, path);
229 Futures.addCallback(tx.submit(), callback);
233 public static String getInterfaceName(final BigInteger datapathid, final String portName, final Integer vlanId) {
234 return String.format("%s:%s:%s", datapathid, portName, vlanId);
237 public static BigInteger getDpnIdFromInterfaceName(String interfaceName) {
238 String[] dpnStr = interfaceName.split(":");
239 BigInteger dpnId = new BigInteger(dpnStr[0]);
243 public static String getTrunkInterfaceName(IdManagerService idManager, String parentInterfaceName,
244 String localHostName, String remoteHostName, String tunnelType) {
245 String tunnelTypeStr;
246 if (tunnelType.contains("TunnelTypeGre")) {
247 tunnelTypeStr = ITMConstants.TUNNEL_TYPE_GRE;
248 } else if (tunnelType.contains("TunnelTypeLogicalGroup")) {
249 tunnelTypeStr = ITMConstants.TUNNEL_TYPE_LOGICAL_GROUP_VXLAN;
251 tunnelTypeStr = ITMConstants.TUNNEL_TYPE_VXLAN;
253 String trunkInterfaceName = String.format("%s:%s:%s:%s", parentInterfaceName, localHostName,
254 remoteHostName, tunnelTypeStr);
255 LOG.trace("trunk interface name is {}", trunkInterfaceName);
256 trunkInterfaceName = String.format("%s%s", TUNNEL, getUniqueIdString(trunkInterfaceName));
257 return trunkInterfaceName;
260 public static void releaseIdForTrunkInterfaceName(IdManagerService idManager, String parentInterfaceName,
261 String localHostName, String remoteHostName, String tunnelType) {
262 String tunnelTypeStr;
263 if (tunnelType.contains("TunnelTypeGre")) {
264 tunnelTypeStr = ITMConstants.TUNNEL_TYPE_GRE;
266 tunnelTypeStr = ITMConstants.TUNNEL_TYPE_VXLAN;
268 String trunkInterfaceName = String.format("%s:%s:%s:%s", parentInterfaceName, localHostName,
269 remoteHostName, tunnelTypeStr);
270 LOG.trace("Releasing Id for trunkInterface - {}", trunkInterfaceName);
271 //releaseId(idManager, trunkInterfaceName) ;
274 public static String getLogicalTunnelGroupName(BigInteger srcDpnId, BigInteger destDpnId) {
275 String tunnelTypeStr = ITMConstants.TUNNEL_TYPE_LOGICAL_GROUP_VXLAN;
276 String groupName = String.format("%s:%s:%s", srcDpnId.toString(), destDpnId.toString(), tunnelTypeStr);
277 LOG.trace("logical tunnel group name is {}", groupName);
278 groupName = String.format("%s%s", TUNNEL, getUniqueIdString(groupName));
282 public static InetAddress getInetAddressFromIpAddress(IpAddress ip) {
283 return InetAddresses.forString(ip.getIpv4Address().getValue());
286 public static InstanceIdentifier<DPNTEPsInfo> getDpnTepInstance(BigInteger dpIdKey) {
287 InstanceIdentifier.InstanceIdentifierBuilder<DPNTEPsInfo> dpnTepInfoBuilder =
288 InstanceIdentifier.builder(DpnEndpoints.class).child(DPNTEPsInfo.class,
289 new DPNTEPsInfoKey(dpIdKey));
290 InstanceIdentifier<DPNTEPsInfo> dpnInfo = dpnTepInfoBuilder.build();
294 public static DPNTEPsInfo createDPNTepInfo(BigInteger dpId, List<TunnelEndPoints> endpoints) {
295 return new DPNTEPsInfoBuilder().setKey(new DPNTEPsInfoKey(dpId)).setTunnelEndPoints(endpoints).build();
298 public static TunnelEndPoints createTunnelEndPoints(BigInteger dpnId, IpAddress ipAddress, String portName,
299 boolean isOfTunnel, int vlanId, IpPrefix prefix,
300 IpAddress gwAddress, List<TzMembership> zones,
301 Class<? extends TunnelTypeBase> tunnelType,
303 // when Interface Mgr provides support to take in Dpn Id
304 return new TunnelEndPointsBuilder().setKey(new TunnelEndPointsKey(ipAddress, portName,tunnelType, vlanId))
305 .setSubnetMask(prefix).setGwIpAddress(gwAddress).setTzMembership(zones)
306 .setOptionOfTunnel(isOfTunnel).setInterfaceName(ItmUtils.getInterfaceName(dpnId, portName, vlanId))
307 .setTunnelType(tunnelType)
308 .setOptionTunnelTos(tos)
312 public static DpnEndpoints createDpnEndpoints(List<DPNTEPsInfo> dpnTepInfo) {
313 return new DpnEndpointsBuilder().setDPNTEPsInfo(dpnTepInfo).build();
316 public static InstanceIdentifier<Interface> buildId(String interfaceName) {
317 InstanceIdentifierBuilder<Interface> idBuilder =
318 InstanceIdentifier.builder(Interfaces.class).child(Interface.class, new InterfaceKey(interfaceName));
319 InstanceIdentifier<Interface> id = idBuilder.build();
323 public static InstanceIdentifier<IfTunnel> buildTunnelId(String ifName) {
324 InstanceIdentifier<IfTunnel> tunnelInstIdentifier = InstanceIdentifier.builder(Interfaces.class)
325 .child(Interface.class, new InterfaceKey(ifName)).augmentation(IfTunnel.class).build();
326 return tunnelInstIdentifier;
329 public static Interface buildLogicalTunnelInterface(BigInteger dpn, String ifName, String desc, boolean enabled) {
330 InterfaceBuilder builder = new InterfaceBuilder().setKey(new InterfaceKey(ifName)).setName(ifName)
331 .setDescription(desc).setEnabled(enabled).setType(Tunnel.class);
332 ParentRefs parentRefs = new ParentRefsBuilder().setDatapathNodeIdentifier(dpn).build();
333 builder.addAugmentation(ParentRefs.class, parentRefs);
335 IfTunnel tunnel = new IfTunnelBuilder().setTunnelDestination(new IpAddress("0.0.0.0".toCharArray()))
336 .setTunnelSource(new IpAddress("0.0.0.0".toCharArray())).setInternal(true).setMonitorEnabled(false)
337 .setTunnelInterfaceType(TunnelTypeLogicalGroup.class).setTunnelRemoteIpFlow(false).build();
338 builder.addAugmentation(IfTunnel.class, tunnel);
339 return builder.build();
342 public static Interface buildTunnelInterface(BigInteger dpn, String ifName, String desc, boolean enabled,
343 Class<? extends TunnelTypeBase> tunType, IpAddress localIp,
344 IpAddress remoteIp, IpAddress gatewayIp, Integer vlanId,
345 boolean internal, Boolean monitorEnabled,
346 Class<? extends TunnelMonitoringTypeBase> monitorProtocol,
347 Integer monitorInterval, boolean useOfTunnel,
348 List<TunnelOptions> tunOptions) {
350 return buildTunnelInterface(dpn, ifName, desc, enabled, tunType, localIp, remoteIp, gatewayIp, vlanId,
351 internal, monitorEnabled, monitorProtocol, monitorInterval, useOfTunnel, null,
355 public static Interface buildTunnelInterface(BigInteger dpn, String ifName, String desc, boolean enabled,
356 Class<? extends TunnelTypeBase> tunType, IpAddress localIp,
357 IpAddress remoteIp, IpAddress gatewayIp, Integer vlanId,
358 boolean internal, Boolean monitorEnabled,
359 Class<? extends TunnelMonitoringTypeBase> monitorProtocol,
360 Integer monitorInterval, boolean useOfTunnel, String parentIfaceName,
361 List<TunnelOptions> tunnelOptions) {
362 InterfaceBuilder builder = new InterfaceBuilder().setKey(new InterfaceKey(ifName)).setName(ifName)
363 .setDescription(desc).setEnabled(enabled).setType(Tunnel.class);
364 ParentRefs parentRefs =
365 new ParentRefsBuilder().setDatapathNodeIdentifier(dpn).setParentInterface(parentIfaceName).build();
366 builder.addAugmentation(ParentRefs.class, parentRefs);
367 Long monitoringInterval = null;
369 IfL2vlan l2vlan = new IfL2vlanBuilder().setVlanId(new VlanId(vlanId)).build();
370 builder.addAugmentation(IfL2vlan.class, l2vlan);
372 LOG.debug("buildTunnelInterface: monitorProtocol = {} and monitorInterval = {}",
373 monitorProtocol.getName(),monitorInterval);
375 if (monitorInterval != null) {
376 monitoringInterval = monitorInterval.longValue();
379 IfTunnel tunnel = new IfTunnelBuilder().setTunnelDestination(remoteIp).setTunnelGateway(gatewayIp)
380 .setTunnelSource(localIp).setTunnelInterfaceType(tunType).setInternal(internal)
381 .setMonitorEnabled(monitorEnabled).setMonitorProtocol(monitorProtocol)
382 .setMonitorInterval(monitoringInterval).setTunnelRemoteIpFlow(useOfTunnel)
383 .setTunnelOptions(tunnelOptions)
385 builder.addAugmentation(IfTunnel.class, tunnel);
386 return builder.build();
389 public static Interface buildHwTunnelInterface(String tunnelIfName, String desc, boolean enabled, String topoId,
390 String nodeId, Class<? extends TunnelTypeBase> tunType,
391 IpAddress srcIp, IpAddress destIp, IpAddress gwIp,
392 Boolean monitorEnabled,
393 Class<? extends TunnelMonitoringTypeBase> monitorProtocol,
394 Integer monitorInterval) {
395 InterfaceBuilder builder = new InterfaceBuilder().setKey(new InterfaceKey(tunnelIfName))
396 .setName(tunnelIfName).setDescription(desc).setEnabled(enabled).setType(Tunnel.class);
397 List<NodeIdentifier> nodeIds = new ArrayList<>();
398 NodeIdentifier hwNode = new NodeIdentifierBuilder().setKey(new NodeIdentifierKey(topoId))
399 .setTopologyId(topoId).setNodeId(nodeId).build();
401 ParentRefs parent = new ParentRefsBuilder().setNodeIdentifier(nodeIds).build();
402 builder.addAugmentation(ParentRefs.class, parent);
403 Long monitoringInterval = (long) ITMConstants.DEFAULT_MONITOR_INTERVAL;
404 Boolean monitoringEnabled = true;
405 Class<? extends TunnelMonitoringTypeBase> monitoringProtocol = ITMConstants.DEFAULT_MONITOR_PROTOCOL;
406 if (monitoringInterval != null) {
407 monitoringInterval = monitorInterval.longValue();
409 if (monitorEnabled != null) {
410 monitoringEnabled = monitorEnabled;
412 if (monitorProtocol != null) {
413 monitoringProtocol = monitorProtocol;
415 IfTunnel tunnel = new IfTunnelBuilder().setTunnelDestination(destIp).setTunnelGateway(gwIp)
416 .setTunnelSource(srcIp).setMonitorEnabled(monitoringEnabled).setMonitorProtocol(monitorProtocol)
417 .setMonitorInterval(100L).setTunnelInterfaceType(tunType).setInternal(false).build();
418 builder.addAugmentation(IfTunnel.class, tunnel);
419 LOG.trace("iftunnel {} built from hwvtep {} ", tunnel, nodeId);
420 return builder.build();
424 public static InternalTunnel buildInternalTunnel(BigInteger srcDpnId, BigInteger dstDpnId,
425 Class<? extends TunnelTypeBase> tunType,
426 String trunkInterfaceName) {
427 InternalTunnel tnl = new InternalTunnelBuilder().setKey(new InternalTunnelKey(dstDpnId, srcDpnId, tunType))
428 .setDestinationDPN(dstDpnId)
429 .setSourceDPN(srcDpnId).setTransportType(tunType)
430 .setTunnelInterfaceNames(Collections.singletonList(trunkInterfaceName)).build();
434 public static ExternalTunnel buildExternalTunnel(String srcNode, String dstNode,
435 Class<? extends TunnelTypeBase> tunType,
436 String trunkInterfaceName) {
437 ExternalTunnel extTnl = new ExternalTunnelBuilder().setKey(
438 new ExternalTunnelKey(dstNode, srcNode, tunType))
439 .setSourceDevice(srcNode).setDestinationDevice(dstNode)
440 .setTunnelInterfaceName(trunkInterfaceName)
441 .setTransportType(tunType).build();
445 public static List<DPNTEPsInfo> getTunnelMeshInfo(DataBroker dataBroker) {
446 List<DPNTEPsInfo> dpnTEPs = null ;
448 // Read the Mesh Information from Cache if not read from the DS
449 dpnTEPs = getTunnelMeshInfo() ;
450 if (dpnTEPs != null) {
454 // Read the EndPoint Info from the operational database
455 InstanceIdentifierBuilder<DpnEndpoints> depBuilder = InstanceIdentifier.builder(DpnEndpoints.class);
456 InstanceIdentifier<DpnEndpoints> deps = depBuilder.build();
457 Optional<DpnEndpoints> dpnEps = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, deps, dataBroker);
458 if (dpnEps.isPresent()) {
459 DpnEndpoints tn = dpnEps.get();
460 dpnTEPs = tn.getDPNTEPsInfo();
461 LOG.debug("Read from CONFIGURATION datastore - No. of Dpns " , dpnTEPs.size());
463 LOG.debug("No Dpn information in CONFIGURATION datastore ");
468 // Reading the Mesh Information from Cache
469 public static List<DPNTEPsInfo> getTunnelMeshInfo() {
470 List<DPNTEPsInfo> dpnTepsInfo = null ;
471 List<Object> values = null ;
473 values = DataStoreCache.getValues(ITMConstants.DPN_TEPs_Info_CACHE_NAME);
474 if (values != null) {
475 dpnTepsInfo = new ArrayList<>() ;
476 for (Object value : values) {
477 dpnTepsInfo.add((DPNTEPsInfo)value) ;
483 public static int getUniqueId(IdManagerService idManager, String idKey) {
484 AllocateIdInput getIdInput = new AllocateIdInputBuilder()
485 .setPoolName(ITMConstants.ITM_IDPOOL_NAME)
486 .setIdKey(idKey).build();
489 Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
490 RpcResult<AllocateIdOutput> rpcResult = result.get();
491 if (rpcResult.isSuccessful()) {
492 return rpcResult.getResult().getIdValue().intValue();
494 LOG.warn("RPC Call to Get Unique Id returned with Errors {}", rpcResult.getErrors());
496 } catch (InterruptedException | ExecutionException e) {
497 LOG.warn("Exception when getting Unique Id",e);
502 public static String getUniqueIdString(String idKey) {
503 return UUID.nameUUIDFromBytes(idKey.getBytes()).toString().substring(0, 12).replace("-", "");
506 public static void releaseId(IdManagerService idManager, String idKey) {
507 ReleaseIdInput idInput =
508 new ReleaseIdInputBuilder().setPoolName(ITMConstants.ITM_IDPOOL_NAME).setIdKey(idKey).build();
510 Future<RpcResult<Void>> result = idManager.releaseId(idInput);
511 RpcResult<Void> rpcResult = result.get();
512 if (!rpcResult.isSuccessful()) {
513 LOG.warn("RPC Call to Get Unique Id returned with Errors {}", rpcResult.getErrors());
515 } catch (InterruptedException | ExecutionException e) {
516 LOG.warn("Exception when getting Unique Id for key {}", idKey, e);
520 public static List<DPNTEPsInfo> getDpnTepListFromDpnId(DataBroker dataBroker, List<BigInteger> dpnIds) {
521 List<DPNTEPsInfo> meshedDpnList = getTunnelMeshInfo(dataBroker) ;
522 List<DPNTEPsInfo> cfgDpnList = new ArrayList<>();
523 if (null != meshedDpnList) {
524 for (BigInteger dpnId : dpnIds) {
525 for (DPNTEPsInfo teps : meshedDpnList) {
526 if (dpnId.equals(teps.getDPNID())) {
527 cfgDpnList.add(teps);
535 @SuppressWarnings("checkstyle:IllegalCatch")
536 public static void setUpOrRemoveTerminatingServiceTable(BigInteger dpnId, IMdsalApiManager mdsalManager,
538 String logmsg = addFlag ? "Installing" : "Removing";
539 LOG.trace(logmsg + " PUNT to Controller flow in DPN {} ", dpnId);
540 List<ActionInfo> listActionInfo = new ArrayList<>();
541 listActionInfo.add(new ActionPuntToController());
544 List<MatchInfo> mkMatches = new ArrayList<>();
546 mkMatches.add(new MatchTunnelId(BigInteger.valueOf(ITMConstants.LLDP_SERVICE_ID)));
548 List<InstructionInfo> mkInstructions = new ArrayList<>();
549 mkInstructions.add(new InstructionApplyActions(listActionInfo));
551 FlowEntity terminatingServiceTableFlowEntity = MDSALUtil
552 .buildFlowEntity(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE,
553 getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE, ITMConstants.LLDP_SERVICE_ID),
554 5, String.format("%s:%d","ITM Flow Entry ", ITMConstants.LLDP_SERVICE_ID), 0, 0,
555 ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(ITMConstants.LLDP_SERVICE_ID)),
556 mkMatches, mkInstructions);
558 mdsalManager.installFlow(terminatingServiceTableFlowEntity);
560 mdsalManager.removeFlow(terminatingServiceTableFlowEntity);
562 } catch (Exception e) {
563 LOG.error("Error while setting up Table 36 for {}", dpnId, e);
567 private static String getFlowRef(long termSvcTable, int svcId) {
568 return String.valueOf(termSvcTable) + svcId;
571 public static InstanceIdentifier<VtepConfigSchema> getVtepConfigSchemaIdentifier(String schemaName) {
572 return InstanceIdentifier.builder(VtepConfigSchemas.class)
573 .child(VtepConfigSchema.class, new VtepConfigSchemaKey(schemaName)).build();
576 public static InstanceIdentifier<VtepConfigSchema> getVtepConfigSchemaIdentifier() {
577 return InstanceIdentifier.builder(VtepConfigSchemas.class).child(VtepConfigSchema.class).build();
580 public static InstanceIdentifier<VtepConfigSchemas> getVtepConfigSchemasIdentifier() {
581 return InstanceIdentifier.builder(VtepConfigSchemas.class).build();
584 public static InstanceIdentifier<VtepIpPool> getVtepIpPoolIdentifier(String subnetCidr) {
585 return InstanceIdentifier.builder(VtepIpPools.class).child(VtepIpPool.class, new VtepIpPoolKey(subnetCidr))
589 public static VtepConfigSchema validateForAddVtepConfigSchema(VtepConfigSchema schema,
590 List<VtepConfigSchema> existingSchemas) {
591 VtepConfigSchema validSchema = validateVtepConfigSchema(schema);
592 for (VtepConfigSchema existingSchema : emptyIfNull(existingSchemas)) {
593 if (!StringUtils.equalsIgnoreCase(schema.getSchemaName(), existingSchema.getSchemaName())
594 && schema.getSubnet().equals(existingSchema.getSubnet())) {
595 String subnetCidr = getSubnetCidrAsString(schema.getSubnet());
596 Preconditions.checkArgument(false, "VTEP schema with subnet [" + subnetCidr
597 + "] already exists. Multiple VTEP schemas with same subnet is not allowed.");
600 if (isNotEmpty(getDpnIdList(validSchema.getDpnIds()))) {
601 String tzone = validSchema.getTransportZoneName();
602 List<BigInteger> lstDpns = getConflictingDpnsAlreadyConfiguredWithTz(validSchema.getSchemaName(), tzone,
603 getDpnIdList(validSchema.getDpnIds()), existingSchemas);
604 if (!lstDpns.isEmpty()) {
605 Preconditions.checkArgument(false, "DPN's " + lstDpns + " already configured for transport zone "
606 + tzone + ". Only one end point per transport Zone per Dpn is allowed.");
608 if (schema.getTunnelType().equals(TunnelTypeGre.class)) {
609 validateForSingleGreTep(validSchema.getSchemaName(), getDpnIdList(validSchema.getDpnIds()),
616 private static void validateForSingleGreTep(String schemaName, List<BigInteger> lstDpnsForAdd,
617 List<VtepConfigSchema> existingSchemas) {
618 for (VtepConfigSchema existingSchema : emptyIfNull(existingSchemas)) {
619 if (TunnelTypeGre.class.equals(existingSchema.getTunnelType())
620 && !StringUtils.equalsIgnoreCase(schemaName, existingSchema.getSchemaName())) {
621 List<BigInteger> lstConflictingDpns = new ArrayList<>(getDpnIdList(existingSchema.getDpnIds()));
622 lstConflictingDpns.retainAll(emptyIfNull(lstDpnsForAdd));
623 if (!lstConflictingDpns.isEmpty()) {
624 String errMsg = "DPN's " + lstConflictingDpns
625 + " already configured with GRE TEP. Mutiple GRE TEP's on a single DPN are not allowed.";
626 Preconditions.checkArgument(false, errMsg);
632 public static VtepConfigSchema validateVtepConfigSchema(VtepConfigSchema schema) {
633 Preconditions.checkNotNull(schema);
634 Preconditions.checkArgument(StringUtils.isNotBlank(schema.getSchemaName()));
635 Preconditions.checkArgument(StringUtils.isNotBlank(schema.getPortName()));
636 Preconditions.checkArgument(schema.getVlanId() >= 0 && schema.getVlanId() < 4095,
637 "Invalid VLAN ID, range (0-4094)");
638 Preconditions.checkArgument(StringUtils.isNotBlank(schema.getTransportZoneName()));
639 Preconditions.checkNotNull(schema.getSubnet());
640 String subnetCidr = getSubnetCidrAsString(schema.getSubnet());
641 SubnetUtils subnetUtils = new SubnetUtils(subnetCidr);
642 IpAddress gatewayIp = schema.getGatewayIp();
643 if (gatewayIp != null) {
644 String strGatewayIp = String.valueOf(gatewayIp.getValue());
645 if (!strGatewayIp.equals(ITMConstants.DUMMY_IP_ADDRESS) && !subnetUtils.getInfo().isInRange(strGatewayIp)) {
646 Preconditions.checkArgument(false, "Gateway IP address " + strGatewayIp
647 + " is not in subnet range " + subnetCidr);
650 ItmUtils.getExcludeIpAddresses(schema.getExcludeIpFilter(), subnetUtils.getInfo());
651 return new VtepConfigSchemaBuilder(schema).setTunnelType(schema.getTunnelType()).build();
654 public static String validateTunnelType(String tunnelType) {
655 if (tunnelType == null) {
656 tunnelType = ITMConstants.TUNNEL_TYPE_VXLAN;
658 tunnelType = StringUtils.upperCase(tunnelType);
659 String error = "Invalid tunnel type. Valid values: "
660 + ITMConstants.TUNNEL_TYPE_VXLAN + " | " + ITMConstants.TUNNEL_TYPE_GRE;
661 Preconditions.checkArgument(ITMConstants.TUNNEL_TYPE_VXLAN.equals(tunnelType)
662 || ITMConstants.TUNNEL_TYPE_GRE.equals(tunnelType), error);
667 private static List<BigInteger> getConflictingDpnsAlreadyConfiguredWithTz(String schemaName, String tzone,
668 List<BigInteger> lstDpns,
669 List<VtepConfigSchema> existingSchemas) {
670 List<BigInteger> lstConflictingDpns = new ArrayList<>();
671 for (VtepConfigSchema schema : emptyIfNull(existingSchemas)) {
672 if (!StringUtils.equalsIgnoreCase(schemaName, schema.getSchemaName())
673 && StringUtils.equals(schema.getTransportZoneName(), tzone)) {
674 lstConflictingDpns = new ArrayList<>(getDpnIdList(schema.getDpnIds()));
675 lstConflictingDpns.retainAll(lstDpns);
676 if (!lstConflictingDpns.isEmpty()) {
681 return lstConflictingDpns;
684 public static VtepConfigSchema constructVtepConfigSchema(String schemaName, String portName, Integer vlanId,
685 String subnetMask, String gatewayIp, String transportZone,
686 String tunnelType, List<BigInteger> dpnIds,
687 String excludeIpFilter) {
688 IpAddress gatewayIpObj = StringUtils.isBlank(gatewayIp) ? null : new IpAddress(gatewayIp.toCharArray());
689 IpPrefix subnet = StringUtils.isBlank(subnetMask) ? null : new IpPrefix(subnetMask.toCharArray());
690 Class<? extends TunnelTypeBase> tunType ;
691 if (tunnelType.equals(ITMConstants.TUNNEL_TYPE_VXLAN)) {
692 tunType = TunnelTypeVxlan.class ;
694 tunType = TunnelTypeGre.class ;
696 VtepConfigSchemaBuilder schemaBuilder = new VtepConfigSchemaBuilder().setSchemaName(schemaName)
697 .setPortName(portName).setVlanId(vlanId).setSubnet(subnet).setGatewayIp(gatewayIpObj)
698 .setTransportZoneName(transportZone).setTunnelType(tunType).setDpnIds(getDpnIdsListFromBigInt(dpnIds))
699 .setExcludeIpFilter(excludeIpFilter);
700 return schemaBuilder.build();
703 public static List<IpAddress> getExcludeIpAddresses(String excludeIpFilter, SubnetInfo subnetInfo) {
704 final List<IpAddress> lstIpAddress = new ArrayList<>();
705 if (StringUtils.isBlank(excludeIpFilter)) {
708 final String[] arrIps = StringUtils.split(excludeIpFilter, ',');
709 for (String ip : arrIps) {
710 if (StringUtils.countMatches(ip, "-") == 1) {
711 final String[] arrIpRange = StringUtils.split(ip, '-');
712 String strStartIp = StringUtils.trim(arrIpRange[0]);
713 String strEndIp = StringUtils.trim(arrIpRange[1]);
714 Preconditions.checkArgument(InetAddresses.isInetAddress(strStartIp),
715 "Invalid exclude IP filter: invalid IP address value " + strStartIp);
716 Preconditions.checkArgument(InetAddresses.isInetAddress(strEndIp),
717 "Invalid exclude IP filter: invalid IP address value " + strEndIp);
718 Preconditions.checkArgument(subnetInfo.isInRange(strStartIp),
719 "Invalid exclude IP filter: IP address [" + strStartIp
720 + "] not in subnet range " + subnetInfo.getCidrSignature());
721 Preconditions.checkArgument(subnetInfo.isInRange(strEndIp),
722 "Invalid exclude IP filter: IP address [" + strEndIp
723 + "] not in subnet range " + subnetInfo.getCidrSignature());
724 int startIp = subnetInfo.asInteger(strStartIp);
725 int endIp = subnetInfo.asInteger(strEndIp);
727 Preconditions.checkArgument(startIp < endIp,
728 "Invalid exclude IP filter: Invalid range [" + ip + "] ");
729 for (int iter = startIp; iter <= endIp; iter++) {
730 String ipAddress = ipFormat(toIpArray(iter));
731 validateAndAddIpAddressToList(subnetInfo, lstIpAddress, ipAddress);
734 validateAndAddIpAddressToList(subnetInfo, lstIpAddress, ip);
740 private static void validateAndAddIpAddressToList(SubnetInfo subnetInfo, final List<IpAddress> lstIpAddress,
742 String ip = StringUtils.trim(ipAddress);
743 Preconditions.checkArgument(InetAddresses.isInetAddress(ip),
744 "Invalid exclude IP filter: invalid IP address value " + ip);
745 Preconditions.checkArgument(subnetInfo.isInRange(ip),
746 "Invalid exclude IP filter: IP address [" + ip + "] not in subnet range "
747 + subnetInfo.getCidrSignature());
748 lstIpAddress.add(new IpAddress(ip.toCharArray()));
751 private static int[] toIpArray(int val) {
752 int[] ret = new int[4];
753 for (int iter = 3; iter >= 0; --iter) {
754 ret[iter] |= val >>> 8 * (3 - iter) & 0xff;
759 private static String ipFormat(int[] octets) {
760 StringBuilder str = new StringBuilder();
761 for (int iter = 0; iter < octets.length; ++iter) {
762 str.append(octets[iter]);
763 if (iter != octets.length - 1) {
767 return str.toString();
770 public static VtepConfigSchema validateForUpdateVtepSchema(String schemaName, List<BigInteger> lstDpnsForAdd,
771 List<BigInteger> lstDpnsForDelete,
772 IITMProvider itmProvider) {
773 Preconditions.checkArgument(StringUtils.isNotBlank(schemaName));
774 if ((lstDpnsForAdd == null || lstDpnsForAdd.isEmpty())
775 && (lstDpnsForDelete == null || lstDpnsForDelete.isEmpty())) {
776 Preconditions.checkArgument(false,
777 "DPN ID list for add | delete is null or empty in schema " + schemaName);
779 VtepConfigSchema schema = itmProvider.getVtepConfigSchema(schemaName);
780 if (schema == null) {
781 Preconditions.checkArgument(false, "Specified VTEP Schema [" + schemaName
782 + "] doesn't exists!");
784 List<BigInteger> existingDpnIds = getDpnIdList(schema.getDpnIds());
785 if (isNotEmpty(lstDpnsForAdd)) {
786 // if (isNotEmpty(existingDpnIds)) {
787 List<BigInteger> lstAlreadyExistingDpns = new ArrayList<>(existingDpnIds);
788 lstAlreadyExistingDpns.retainAll(lstDpnsForAdd);
789 Preconditions.checkArgument(lstAlreadyExistingDpns.isEmpty(),
790 "DPN ID's " + lstAlreadyExistingDpns
791 + " already exists in VTEP schema [" + schemaName + "]");
793 if (schema.getTunnelType().equals(TunnelTypeGre.class)) {
794 validateForSingleGreTep(schema.getSchemaName(), lstDpnsForAdd, itmProvider.getAllVtepConfigSchemas());
797 if (isNotEmpty(lstDpnsForDelete)) {
798 if (existingDpnIds == null || existingDpnIds.isEmpty()) {
799 String builder = "DPN ID's " + lstDpnsForDelete
800 + " specified for delete from VTEP schema [" + schemaName
801 + "] are not configured in the schema.";
802 Preconditions.checkArgument(false, builder);
803 } else if (!existingDpnIds.containsAll(lstDpnsForDelete)) {
804 List<BigInteger> lstConflictingDpns = new ArrayList<>(lstDpnsForDelete);
805 lstConflictingDpns.removeAll(existingDpnIds);
806 String builder = "DPN ID's " + lstConflictingDpns
807 + " specified for delete from VTEP schema [" + schemaName
808 + "] are not configured in the schema.";
809 Preconditions.checkArgument(false, builder);
815 public static String getSubnetCidrAsString(IpPrefix subnet) {
816 return subnet == null ? StringUtils.EMPTY : String.valueOf(subnet.getValue());
819 public static <T> List<T> emptyIfNull(List<T> list) {
820 return list == null ? Collections.emptyList() : list;
823 public static <T> boolean isEmpty(Collection<T> collection) {
824 return collection == null || collection.isEmpty();
827 public static <T> boolean isNotEmpty(Collection<T> collection) {
828 return !isEmpty(collection);
831 public static HwVtep createHwVtepObject(String topoId, String nodeId, IpAddress ipAddress, IpPrefix ipPrefix,
832 IpAddress gatewayIP, int vlanID,
833 Class<? extends TunnelTypeBase> tunneltype, TransportZone transportZone) {
834 HwVtep hwVtep = new HwVtep();
835 hwVtep.setGatewayIP(gatewayIP);
836 hwVtep.setHwIp(ipAddress);
837 hwVtep.setIpPrefix(ipPrefix);
838 hwVtep.setNodeId(nodeId);
839 hwVtep.setTopoId(topoId);
840 hwVtep.setTransportZone(transportZone.getZoneName());
841 hwVtep.setTunnelType(tunneltype);
842 hwVtep.setVlanID(vlanID);
846 public static String getHwParentIf(String topoId, String srcNodeid) {
847 return String.format("%s:%s", topoId, srcNodeid);
850 public static <T extends DataObject> void syncWrite(LogicalDatastoreType datastoreType,
851 InstanceIdentifier<T> path, T data, DataBroker broker) {
852 WriteTransaction tx = broker.newWriteOnlyTransaction();
853 tx.put(datastoreType, path, data, true);
854 CheckedFuture<Void, TransactionCommitFailedException> futures = tx.submit();
857 } catch (InterruptedException | ExecutionException e) {
858 LOG.error("ITMUtils:SyncWrite , Error writing to datastore (path, data) : ({}, {})", path, data);
859 throw new RuntimeException(e.getMessage());
863 public static List<BigInteger> getDpnIdList(List<DpnIds> dpnIds) {
864 List<BigInteger> dpnList = new ArrayList<>() ;
865 for (DpnIds dpn : dpnIds) {
866 dpnList.add(dpn.getDPN()) ;
871 public static List<DpnIds> getDpnIdsListFromBigInt(List<BigInteger> dpnIds) {
872 List<DpnIds> dpnIdList = new ArrayList<>();
873 DpnIdsBuilder builder = new DpnIdsBuilder();
874 for (BigInteger dpnId : dpnIds) {
875 dpnIdList.add(builder.setKey(new DpnIdsKey(dpnId)).setDPN(dpnId).build());
880 public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
881 .interfaces.state.Interface> buildStateInterfaceId(String interfaceName) {
882 InstanceIdentifierBuilder<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
883 .interfaces.state.Interface> idBuilder = InstanceIdentifier.builder(InterfacesState.class)
884 .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
885 .interfaces.state.Interface.class,
886 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
887 .interfaces.state.InterfaceKey(interfaceName));
888 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
889 .interfaces.state.Interface> id = idBuilder.build();
893 public static Boolean readMonitoringStateFromCache(DataBroker dataBroker) {
894 InstanceIdentifier<TunnelMonitorParams> iid = InstanceIdentifier.create(TunnelMonitorParams.class);
895 TunnelMonitorParams tunnelMonitorParams = (TunnelMonitorParams) DataStoreCache
896 .get(ITMConstants.ITM_MONIRORING_PARAMS_CACHE_NAME,iid,"MonitorParams",dataBroker,true);
897 if (tunnelMonitorParams != null) {
898 return tunnelMonitorParams.isEnabled();
900 return ITMConstants.DEFAULT_MONITOR_ENABLED;
904 public static Integer readMonitorIntervalfromCache(DataBroker dataBroker) {
905 InstanceIdentifier<TunnelMonitorInterval> iid = InstanceIdentifier.create(TunnelMonitorInterval.class);
906 TunnelMonitorInterval tunnelMonitorIOptional = (TunnelMonitorInterval)DataStoreCache
907 .get(ITMConstants.ITM_MONIRORING_PARAMS_CACHE_NAME,iid,"Interval",dataBroker,true);
908 if (tunnelMonitorIOptional != null) {
909 return tunnelMonitorIOptional.getInterval();
915 public static Integer determineMonitorInterval(DataBroker dataBroker) {
916 Integer monitorInterval = ItmUtils.readMonitorIntervalfromCache(dataBroker);
917 LOG.debug("determineMonitorInterval: monitorInterval from DS = {}", monitorInterval);
918 if (monitorInterval == null) {
919 Class<? extends TunnelMonitoringTypeBase> monitorProtocol = determineMonitorProtocol(dataBroker);
920 if (monitorProtocol.isAssignableFrom(TunnelMonitoringTypeBfd.class)) {
921 monitorInterval = ITMConstants.BFD_DEFAULT_MONITOR_INTERVAL;
923 monitorInterval = ITMConstants.DEFAULT_MONITOR_INTERVAL;
926 LOG.debug("determineMonitorInterval: monitorInterval = {}", monitorInterval);
927 InstanceIdentifier<TunnelMonitorInterval> iid = InstanceIdentifier.builder(TunnelMonitorInterval.class).build();
928 TunnelMonitorInterval intervalBuilder = new TunnelMonitorIntervalBuilder().setInterval(monitorInterval).build();
929 ItmUtils.asyncUpdate(LogicalDatastoreType.OPERATIONAL,iid, intervalBuilder, dataBroker,
930 ItmUtils.DEFAULT_CALLBACK);
931 return monitorInterval;
934 public static List<String> getInternalTunnelInterfaces(DataBroker dataBroker) {
935 List<String> tunnelList = new ArrayList<>();
936 Collection<String> internalInterfaces = itmCache.getAllInternalInterfaces();
937 if (internalInterfaces == null) {
938 updateTunnelsCache(dataBroker);
939 internalInterfaces = itmCache.getAllInternalInterfaces();
941 LOG.debug("ItmUtils.getTunnelList Cache Internal Interfaces size: {} ", internalInterfaces.size());
942 if (internalInterfaces != null) {
943 tunnelList.addAll(internalInterfaces);
945 LOG.trace("ItmUtils.getTunnelList Internal: {}", tunnelList);
949 public static List<String> getTunnelsofTzone(List<HwVtep> hwVteps, String tzone, DataBroker dataBroker,
950 Boolean hwVtepsExist) {
952 List<String> tunnels = new ArrayList<>();
953 InstanceIdentifier<TransportZone> path = InstanceIdentifier.builder(TransportZones.class)
954 .child(TransportZone.class, new TransportZoneKey(tzone)).build();
955 Optional<TransportZone> transportZoneOptional =
956 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
957 if (transportZoneOptional.isPresent()) {
958 TransportZone transportZone = transportZoneOptional.get();
959 Class<? extends TunnelTypeBase> tunType = transportZone.getTunnelType();
960 if (transportZone.getSubnets() != null && !transportZone.getSubnets().isEmpty()) {
961 for (Subnets sub : transportZone.getSubnets()) {
962 if (sub.getVteps() != null && !sub.getVteps().isEmpty()) {
963 for (Vteps vtepLocal : sub.getVteps()) {
964 for (Vteps vtepRemote : sub.getVteps()) {
965 if (!vtepLocal.equals(vtepRemote)) {
966 InternalTunnelKey key = new InternalTunnelKey(vtepRemote.getDpnId(),
967 vtepLocal.getDpnId(), tunType);
968 InstanceIdentifier<InternalTunnel> intIID =
969 InstanceIdentifier.builder(TunnelList.class)
970 .child(InternalTunnel.class, key).build();
971 Optional<InternalTunnel> tunnelsOptional =
972 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, intIID, dataBroker);
973 if (tunnelsOptional.isPresent()) {
974 List<String> tunnelInterfaceNames = tunnelsOptional
975 .get().getTunnelInterfaceNames();
976 if (tunnelInterfaceNames != null && !tunnelInterfaceNames.isEmpty()) {
977 String tunnelInterfaceName = tunnelInterfaceNames.get(0);
978 LOG.trace("Internal Tunnel added {}", tunnelInterfaceName);
979 tunnels.add(tunnelInterfaceName);
984 if (hwVteps != null && !hwVteps.isEmpty()) {
985 for (HwVtep hwVtep : hwVteps) {
986 tunnels.add(getExtTunnel(hwVtep.getNodeId(), vtepLocal.getDpnId().toString(),
987 tunType, dataBroker));
988 tunnels.add(getExtTunnel(vtepLocal.getDpnId().toString(), hwVtep.getNodeId(),
989 tunType, dataBroker));
997 for (HwVtep hwVtep : hwVteps) {
998 for (HwVtep hwVtepOther : hwVteps) {
999 if (!hwVtep.getHwIp().equals(hwVtepOther.getHwIp())) {
1000 tunnels.add(getExtTunnel(hwVtep.getNodeId(), hwVtepOther.getNodeId(),
1001 tunType, dataBroker));
1002 tunnels.add(getExtTunnel(hwVtepOther.getNodeId(), hwVtep.getNodeId(),
1003 tunType, dataBroker));
1012 public static List<String> getInternalTunnelsofTzone(String tzone, DataBroker dataBroker) {
1013 List<String> tunnels = new ArrayList<>();
1014 LOG.trace("Getting internal tunnels of {}",tzone);
1015 InstanceIdentifier<TransportZone> path = InstanceIdentifier.builder(TransportZones.class)
1016 .child(TransportZone.class, new TransportZoneKey(tzone)).build();
1017 Optional<TransportZone> transportZoneOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
1019 if (transportZoneOptional.isPresent()) {
1020 TransportZone transportZone = transportZoneOptional.get();
1021 if (transportZone.getSubnets() != null && !transportZone.getSubnets().isEmpty()) {
1022 for (Subnets sub : transportZone.getSubnets()) {
1023 if (sub.getVteps() != null && !sub.getVteps().isEmpty()) {
1024 for (Vteps vtepLocal : sub.getVteps()) {
1025 for (Vteps vtepRemote : sub.getVteps()) {
1026 if (!vtepLocal.equals(vtepRemote)) {
1027 InternalTunnelKey key =
1028 new InternalTunnelKey(vtepRemote.getDpnId(), vtepLocal.getDpnId(),
1029 transportZone.getTunnelType());
1030 InstanceIdentifier<InternalTunnel> intIID =
1031 InstanceIdentifier.builder(TunnelList.class)
1032 .child(InternalTunnel.class, key).build();
1033 Optional<InternalTunnel> tunnelsOptional =
1034 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, intIID, dataBroker);
1035 if (tunnelsOptional.isPresent()) {
1036 List<String> tunnelInterfaceNames = tunnelsOptional.get()
1037 .getTunnelInterfaceNames();
1038 if (tunnelInterfaceNames != null && !tunnelInterfaceNames.isEmpty()) {
1039 String tunnelInterfaceName = tunnelInterfaceNames.get(0);
1040 LOG.trace("Internal Tunnel added {}", tunnelInterfaceName);
1041 tunnels.add(tunnelInterfaceName);
1054 private static String getExtTunnel(String nodeId, String dpId,Class<? extends TunnelTypeBase> tunType, DataBroker
1056 LOG.trace("getting ext tunnel for {} and dpId {}",nodeId,dpId);
1057 ExternalTunnelKey key = getExternalTunnelKey(dpId, nodeId, tunType);
1058 InstanceIdentifier<ExternalTunnel> intIID = InstanceIdentifier.builder(ExternalTunnelList.class)
1059 .child(ExternalTunnel.class, key).build();
1060 Optional<ExternalTunnel> tunnelsOptional =
1061 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, intIID, dataBroker);
1062 if (tunnelsOptional.isPresent()) {
1063 String tunnelInterfaceName = tunnelsOptional.get().getTunnelInterfaceName();
1064 LOG.trace("ext tunnel returned {} ", tunnelInterfaceName);
1065 return tunnelInterfaceName;
1070 public static ExternalTunnelKey getExternalTunnelKey(String dst , String src,
1071 Class<? extends TunnelTypeBase> tunType) {
1072 if (src.indexOf("physicalswitch") > 0) {
1073 src = src.substring(0, src.indexOf("physicalswitch") - 1);
1075 if (dst.indexOf("physicalswitch") > 0) {
1076 dst = dst.substring(0, dst.indexOf("physicalswitch") - 1);
1078 return new ExternalTunnelKey(dst, src, tunType);
1081 public static List<TunnelEndPoints> getTEPsForDpn(BigInteger srcDpn, List<DPNTEPsInfo> dpnList) {
1082 for (DPNTEPsInfo dpn : dpnList) {
1083 if (dpn.getDPNID().equals(srcDpn)) {
1084 return dpn.getTunnelEndPoints() ;
1090 public static TunnelList getAllInternalTunnels(DataBroker broker) {
1091 InstanceIdentifier<TunnelList> tunnelListInstanceIdentifier =
1092 InstanceIdentifier.builder(TunnelList.class).build();
1093 return read(LogicalDatastoreType.CONFIGURATION, tunnelListInstanceIdentifier, broker).orNull();
1096 public static List<InternalTunnel> getAllInternalTunnels(DataBroker dataBroker,
1097 LogicalDatastoreType datastoreType) {
1098 List<InternalTunnel> result = null;
1099 InstanceIdentifier<TunnelList> iid = InstanceIdentifier.builder(TunnelList.class).build();
1100 Optional<TunnelList> tunnelList = read(LogicalDatastoreType.CONFIGURATION, iid, dataBroker);
1101 if (tunnelList.isPresent()) {
1102 result = tunnelList.get().getInternalTunnel();
1104 if (result == null) {
1105 result = Collections.emptyList();
1110 public static InternalTunnel getInternalTunnel(String interfaceName, DataBroker broker) {
1111 InternalTunnel internalTunnel = null;
1112 internalTunnel = itmCache.getInternalTunnel(interfaceName);
1113 if (internalTunnel == null) {
1114 updateTunnelsCache(broker);
1115 internalTunnel = itmCache.getInternalTunnel(interfaceName);
1117 return internalTunnel;
1120 public static ExternalTunnel getExternalTunnel(String interfaceName, DataBroker broker) {
1121 ExternalTunnel externalTunnel = null;
1122 externalTunnel = itmCache.getExternalTunnel(interfaceName);
1123 if (externalTunnel == null) {
1124 updateTunnelsCache(broker);
1125 externalTunnel = itmCache.getExternalTunnel(interfaceName);
1127 return externalTunnel;
1130 public static List<ExternalTunnel> getAllExternalTunnels(DataBroker broker) {
1131 List<ExternalTunnel> result = null;
1132 InstanceIdentifier<ExternalTunnelList> id = InstanceIdentifier.builder(ExternalTunnelList.class).build();
1133 Optional<ExternalTunnelList> tunnelList = read(LogicalDatastoreType.CONFIGURATION, id, broker);
1134 if (tunnelList.isPresent()) {
1135 result = tunnelList.get().getExternalTunnel();
1137 if (result == null) {
1138 result = Collections.emptyList();
1143 public static List<ExternalTunnel> getAllExternalTunnels(DataBroker dataBroker,
1144 LogicalDatastoreType datastoreType) {
1145 List<ExternalTunnel> result = null;
1146 InstanceIdentifier<ExternalTunnelList> iid = InstanceIdentifier.builder(ExternalTunnelList.class).build();
1147 Optional<ExternalTunnelList> tunnelList = read(LogicalDatastoreType.CONFIGURATION, iid, dataBroker);
1148 if (tunnelList.isPresent()) {
1149 result = tunnelList.get().getExternalTunnel();
1151 if (result == null) {
1152 result = Collections.emptyList();
1157 public static String convertTunnelTypetoString(Class<? extends TunnelTypeBase> tunType) {
1158 String tunnelType = ITMConstants.TUNNEL_TYPE_VXLAN;
1159 if (tunType.equals(TunnelTypeVxlan.class)) {
1160 tunnelType = ITMConstants.TUNNEL_TYPE_VXLAN ;
1161 } else if (tunType.equals(TunnelTypeGre.class)) {
1162 tunnelType = ITMConstants.TUNNEL_TYPE_GRE ;
1163 } else if (tunType.equals(TunnelTypeMplsOverGre.class)) {
1164 tunnelType = ITMConstants.TUNNEL_TYPE_MPLSoGRE;
1165 } else if (tunType.equals(TunnelTypeLogicalGroup.class)) {
1166 tunnelType = ITMConstants.TUNNEL_TYPE_LOGICAL_GROUP_VXLAN;
1172 public static boolean isItmIfType(Class<? extends InterfaceType> ifType) {
1173 return ifType != null && ifType.isAssignableFrom(Tunnel.class);
1176 public static StateTunnelListKey getTunnelStateKey(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
1177 .interfaces.rev140508.interfaces.state.Interface iface) {
1178 StateTunnelListKey key = null;
1179 if (isItmIfType(iface.getType())) {
1180 key = new StateTunnelListKey(iface.getName());
1185 public static void updateTunnelsCache(DataBroker broker) {
1186 List<InternalTunnel> internalTunnels = getAllInternalTunnels(broker, LogicalDatastoreType.CONFIGURATION);
1187 for (InternalTunnel tunnel : internalTunnels) {
1188 itmCache.addInternalTunnel(tunnel);
1190 List<ExternalTunnel> externalTunnels = getAllExternalTunnels(broker, LogicalDatastoreType.CONFIGURATION);
1191 for (ExternalTunnel tunnel : externalTunnels) {
1192 itmCache.addExternalTunnel(tunnel);
1196 public static Interface getInterface(
1197 String name, IInterfaceManager ifaceManager) {
1198 Interface result = itmCache.getInterface(name);
1199 if (result == null) {
1200 result = ifaceManager.getInterfaceInfoFromConfigDataStore(name);
1201 if (result != null) {
1202 itmCache.addInterface(result);
1208 public static StateTunnelList getTunnelState(DataBroker dataBroker, String ifaceName,
1209 InstanceIdentifier<StateTunnelList> stListId) {
1210 StateTunnelList tunnelState = (StateTunnelList)DataStoreCache
1211 .get(ITMConstants.TUNNEL_STATE_CACHE_NAME, ifaceName);
1212 if (tunnelState == null) {
1213 Optional<StateTunnelList> tunnelsState = ItmUtils
1214 .read(LogicalDatastoreType.OPERATIONAL, stListId, dataBroker);
1215 if (tunnelsState.isPresent()) {
1222 public static Class<? extends TunnelMonitoringTypeBase> readMonitoringProtocolFromCache(DataBroker dataBroker) {
1223 InstanceIdentifier<TunnelMonitorParams> iid = InstanceIdentifier.create(TunnelMonitorParams.class);
1224 TunnelMonitorParams tunnelMonitorParams = (TunnelMonitorParams) DataStoreCache
1225 .get(ITMConstants.ITM_MONIRORING_PARAMS_CACHE_NAME,iid,"MonitorParams",dataBroker,true);
1226 if (tunnelMonitorParams != null) {
1227 return tunnelMonitorParams.getMonitorProtocol();
1232 public static Class<? extends TunnelMonitoringTypeBase> determineMonitorProtocol(DataBroker dataBroker) {
1233 Class<? extends TunnelMonitoringTypeBase> monitoringProtocol =
1234 ItmUtils.readMonitoringProtocolFromCache(dataBroker);
1235 LOG.debug("determineMonitorProtocol: monitorProtocol from DS = {}", monitoringProtocol);
1236 if (monitoringProtocol == null) {
1237 monitoringProtocol = ITMConstants.DEFAULT_MONITOR_PROTOCOL;
1239 LOG.debug("determineMonitorProtocol: monitorProtocol = {}", monitoringProtocol);
1240 Boolean monitorState = ItmUtils.readMonitoringStateFromCache(dataBroker);
1241 if (monitorState == null) {
1242 monitorState = true;
1244 LOG.debug("determineMonitorProtocol: monitorState = {}", monitorState);
1245 InstanceIdentifier<TunnelMonitorParams> iid = InstanceIdentifier.builder(TunnelMonitorParams.class).build();
1246 TunnelMonitorParams protocolBuilder = new TunnelMonitorParamsBuilder().setEnabled(monitorState)
1247 .setMonitorProtocol(monitoringProtocol).build();
1248 ItmUtils.asyncUpdate(LogicalDatastoreType.OPERATIONAL,iid, protocolBuilder, dataBroker,
1249 ItmUtils.DEFAULT_CALLBACK);
1250 return monitoringProtocol;
1253 public static List<DcGatewayIp> getDcGatewayIpList(DataBroker broker) {
1254 InstanceIdentifier<DcGatewayIpList> dcGatewayIpListid =
1255 InstanceIdentifier.builder(DcGatewayIpList.class).build();
1256 Optional<DcGatewayIpList> dcGatewayIpListConfig =
1257 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, dcGatewayIpListid, broker);
1258 if (dcGatewayIpListConfig.isPresent()) {
1259 DcGatewayIpList containerList = dcGatewayIpListConfig.get();
1260 if (containerList != null) {
1261 return containerList.getDcGatewayIp();
1267 public static boolean falseIfNull(Boolean value) {
1268 return value == null ? false : value;
1271 public static <T> List<T> getIntersection(List<T> list1, List<T> list2) {
1272 List<T> list = new ArrayList<>();
1273 for (T iter : list1) {
1274 if (list2.contains(iter)) {
1278 LOG.debug(" getIntersection - L1 {}, L2 - {}, Intersection - {}", list1, list2, list);
1282 public static void addTransportZoneMembership(List<TzMembership> zones, String zoneName) {
1283 zones.add(new TzMembershipBuilder().setZoneName(zoneName).build());
1286 public static List<TzMembership> createTransportZoneMembership(String zoneName) {
1287 List<TzMembership> zones = new ArrayList<>();
1288 zones.add(new TzMembershipBuilder().setZoneName(zoneName).build());
1293 * Returns the transport zone from Configuration datastore.
1295 * @param tzName transport zone name
1296 * @param dataBroker data broker handle to perform operations on datastore
1297 * @return the TransportZone object in Config DS
1299 // FIXME: Better is to implement cache to avoid datastore read.
1300 public static TransportZone getTransportZoneFromConfigDS(String tzName, DataBroker dataBroker) {
1301 InstanceIdentifier<TransportZone> tzonePath = InstanceIdentifier.builder(TransportZones.class)
1302 .child(TransportZone.class, new TransportZoneKey(tzName)).build();
1303 Optional<TransportZone> transportZoneOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, tzonePath,
1305 if (transportZoneOptional.isPresent()) {
1306 return transportZoneOptional.get();
1312 * Gets the transport zone in TepsNotHosted list in the Configuration Datastore, based on transport zone name.
1314 * @param unknownTz transport zone name
1316 * @param dataBroker data broker handle to perform read operations on config datastore
1318 * @return the TepsNotHostedInTransportZone object in the TepsNotHosted list in Config DS
1320 public static TepsNotHostedInTransportZone getUnknownTransportZoneFromITMConfigDS(
1321 String unknownTz, DataBroker dataBroker) {
1322 InstanceIdentifier<TepsNotHostedInTransportZone> unknownTzPath =
1323 InstanceIdentifier.builder(TransportZones.class)
1324 .child(TepsNotHostedInTransportZone.class,
1325 new TepsNotHostedInTransportZoneKey(unknownTz)).build();
1326 Optional<TepsNotHostedInTransportZone> unknownTzOptional =
1327 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, unknownTzPath, dataBroker);
1328 if (unknownTzOptional.isPresent()) {
1329 return unknownTzOptional.get();
1335 * Gets the bridge datapath ID from Network topology Node's OvsdbBridgeAugmentation, in the Operational DS.
1337 * @param node Network Topology Node
1339 * @param bridge bridge name
1341 * @param dataBroker data broker handle to perform operations on datastore
1343 * @return the datapath ID of bridge in string form
1345 public static String getBridgeDpid(Node node, String bridge, DataBroker dataBroker) {
1346 OvsdbBridgeAugmentation ovsdbBridgeAugmentation = null;
1347 Node bridgeNode = null;
1348 String datapathId = null;
1350 NodeId ovsdbNodeId = node.getKey().getNodeId();
1352 NodeId brNodeId = new NodeId(ovsdbNodeId.getValue()
1353 + "/" + ITMConstants.BRIDGE_URI_PREFIX + "/" + bridge);
1355 InstanceIdentifier<Node> bridgeIid =
1357 .create(NetworkTopology.class)
1358 .child(Topology.class, new TopologyKey(IfmConstants.OVSDB_TOPOLOGY_ID))
1359 .child(Node.class,new NodeKey(brNodeId));
1361 Optional<Node> opBridgeNode = ItmUtils.read(LogicalDatastoreType.OPERATIONAL, bridgeIid, dataBroker);
1363 if (opBridgeNode.isPresent()) {
1364 bridgeNode = opBridgeNode.get();
1366 if (bridgeNode != null) {
1367 ovsdbBridgeAugmentation = bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class);
1370 if (ovsdbBridgeAugmentation != null && ovsdbBridgeAugmentation.getDatapathId() != null) {
1371 datapathId = ovsdbBridgeAugmentation.getDatapathId().getValue();
1377 * Gets the Network topology Node from Operational Datastore
1378 * based on Bridge Augmentation.
1380 * @param bridgeAugmentation bridge augmentation of OVSDB node
1382 * @param dataBroker data broker handle to perform operations on datastore
1384 * @return the Network Topology Node i.e. OVSDB node which is managing the specified bridge
1386 public static Node getOvsdbNode(OvsdbBridgeAugmentation bridgeAugmentation,
1387 DataBroker dataBroker) {
1388 Node ovsdbNode = null;
1389 Optional<Node> opOvsdbNode = null;
1390 if (bridgeAugmentation != null) {
1391 InstanceIdentifier<Node> ovsdbNodeIid =
1392 (InstanceIdentifier<Node>) bridgeAugmentation.getManagedBy().getValue();
1393 opOvsdbNode = ItmUtils.read(LogicalDatastoreType.OPERATIONAL, ovsdbNodeIid, dataBroker);
1395 if (opOvsdbNode.isPresent()) {
1396 ovsdbNode = opOvsdbNode.get();
1402 * Gets the bridge datapath ID in string form from
1403 * Network topology Node's OvsdbBridgeAugmentation in the Operational DS.
1405 * @param augmentedNode Ovsdb Augmented Network Topology Node
1407 * @return the datapath ID of bridge in string form
1409 public static String getStrDatapathId(OvsdbBridgeAugmentation augmentedNode) {
1410 String datapathId = null;
1411 if (augmentedNode != null && augmentedNode.getDatapathId() != null) {
1412 datapathId = augmentedNode.getDatapathId().getValue();
1418 * Returns the dummy subnet (255.255.255.255/32) as IpPrefix object.
1420 * @return the dummy subnet (255.255.255.255/32) in IpPrefix object
1422 public static IpPrefix getDummySubnet() {
1423 return DUMMY_IP_PREFIX;
1427 * Deletes the transport zone from Configuration datastore.
1429 * @param tzName transport zone name
1430 * @param dataBroker data broker handle to perform operations on datastore
1432 public static void deleteTransportZoneFromConfigDS(String tzName, DataBroker dataBroker) {
1433 // check whether transport-zone exists in config DS.
1434 TransportZone transportZoneFromConfigDS = ItmUtils.getTransportZoneFromConfigDS(tzName, dataBroker);
1435 if (transportZoneFromConfigDS != null) {
1436 // it exists, delete default-TZ now
1437 InstanceIdentifier<TransportZone> path = InstanceIdentifier.builder(TransportZones.class)
1438 .child(TransportZone.class,
1439 new TransportZoneKey(tzName)).build();
1440 LOG.debug("Removing {} transport-zone from config DS.", tzName);
1442 SingleTransactionDataBroker.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, path);
1443 } catch (TransactionCommitFailedException e) {
1444 LOG.error("deleteTransportZoneFromConfigDS failed. {} could not be deleted.", tzName, e);
1450 * Validates the tunnelType argument and returnsTunnelTypeBase class object
1451 * corresponding to tunnelType obtained in String format.
1453 * @param tunnelType type of tunnel in string form
1455 * @return tunnel-type in TunnelTypeBase object
1457 public static Class<? extends TunnelTypeBase> getTunnelType(String tunnelType) {
1458 // validate tunnelType string, in case it is NULL or empty, then
1459 // take VXLAN tunnel type by default
1460 if (tunnelType == null || tunnelType.isEmpty()) {
1461 return TUNNEL_TYPE_MAP.get(ITMConstants.TUNNEL_TYPE_VXLAN);
1462 } else if (!tunnelType.equals(ITMConstants.TUNNEL_TYPE_VXLAN)
1463 && !tunnelType.equals(ITMConstants.TUNNEL_TYPE_GRE)) {
1464 // if tunnel type is some incorrect value, then
1465 // take VXLAN tunnel type by default
1466 return TUNNEL_TYPE_MAP.get(ITMConstants.TUNNEL_TYPE_VXLAN);
1469 // return TunnelTypeBase object corresponding to tunnel-type
1470 return TUNNEL_TYPE_MAP.get(tunnelType);
1473 public static List<TzMembership> removeTransportZoneMembership(TunnelEndPoints endPts, List<TzMembership> zones) {
1474 LOG.trace(" RemoveTransportZoneMembership TEPs {}, Membership to be removed {} ", endPts, zones);
1475 List<TzMembership> existingTzList = new ArrayList<>(endPts.getTzMembership()) ;
1476 for (TzMembership membership : zones) {
1477 existingTzList.remove(new TzMembershipBuilder().setZoneName(membership.getZoneName()).build());
1479 LOG.debug("Modified Membership List {}", existingTzList);
1480 return existingTzList;
1483 public static List<TzMembership> getOriginalTzMembership(TunnelEndPoints srcTep, BigInteger dpnId,
1484 List<DPNTEPsInfo> meshedDpnList) {
1485 LOG.trace("Original Membership for source DPN {}, source TEP {}", dpnId, srcTep);
1486 for (DPNTEPsInfo dstDpn : meshedDpnList) {
1487 if (dpnId.equals(dstDpn.getDPNID())) {
1488 List<TunnelEndPoints> endPts = dstDpn.getTunnelEndPoints();
1489 for (TunnelEndPoints tep : endPts) {
1490 if (tep.getIpAddress().equals(srcTep.getIpAddress())) {
1491 LOG.debug("Original Membership size " + tep.getTzMembership().size()) ;
1492 return tep.getTzMembership();
1500 public static StateTunnelList buildStateTunnelList(StateTunnelListKey tlKey, String name, boolean state,
1501 TunnelOperStatus tunOpStatus, IInterfaceManager ifaceManager,
1502 DataBroker broker) {
1503 StateTunnelListBuilder stlBuilder = new StateTunnelListBuilder();
1504 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface =
1505 ItmUtils.getInterface(name, ifaceManager);
1506 IfTunnel ifTunnel = iface.getAugmentation(IfTunnel.class);
1507 ParentRefs parentRefs = iface.getAugmentation(ParentRefs.class);
1508 if (ifTunnel == null && parentRefs == null) {
1511 DstInfoBuilder dstInfoBuilder = new DstInfoBuilder();
1512 SrcInfoBuilder srcInfoBuilder = new SrcInfoBuilder();
1513 dstInfoBuilder.setTepIp(ifTunnel.getTunnelDestination());
1514 srcInfoBuilder.setTepIp(ifTunnel.getTunnelSource());
1515 // TODO: Add/Improve logic for device type
1516 InternalTunnel internalTunnel = ItmUtils.itmCache.getInternalTunnel(name);
1517 ExternalTunnel externalTunnel = ItmUtils.itmCache.getExternalTunnel(name);
1518 if (internalTunnel == null && externalTunnel == null) {
1519 // both not present in cache. let us update and try again.
1520 ItmUtils.updateTunnelsCache(broker);
1521 internalTunnel = ItmUtils.itmCache.getInternalTunnel(name);
1522 externalTunnel = ItmUtils.itmCache.getExternalTunnel(name);
1524 if (internalTunnel != null) {
1525 srcInfoBuilder.setTepDeviceId(internalTunnel.getSourceDPN().toString())
1526 .setTepDeviceType(TepTypeInternal.class);
1527 dstInfoBuilder.setTepDeviceId(internalTunnel.getDestinationDPN().toString())
1528 .setTepDeviceType(TepTypeInternal.class);
1529 stlBuilder.setTransportType(internalTunnel.getTransportType());
1530 } else if (externalTunnel != null) {
1531 ExternalTunnel tunnel = ItmUtils.itmCache.getExternalTunnel(name);
1532 srcInfoBuilder.setTepDeviceId(tunnel.getSourceDevice())
1533 .setTepDeviceType(getDeviceType(tunnel.getSourceDevice()));
1534 dstInfoBuilder.setTepDeviceId(tunnel.getDestinationDevice())
1535 .setTepDeviceType(getDeviceType(tunnel.getDestinationDevice()))
1536 .setTepIp(ifTunnel.getTunnelDestination());
1537 stlBuilder.setTransportType(tunnel.getTransportType());
1539 stlBuilder.setKey(tlKey).setTunnelInterfaceName(name).setOperState(tunOpStatus).setTunnelState(state)
1540 .setDstInfo(dstInfoBuilder.build()).setSrcInfo(srcInfoBuilder.build());
1541 return stlBuilder.build();
1544 public static Class<? extends TepTypeBase> getDeviceType(String device) {
1545 if (device.startsWith("hwvtep")) {
1546 return TepTypeHwvtep.class;
1547 } else if (device.contains("IpAddress")) {
1548 return TepTypeExternal.class;
1550 return TepTypeInternal.class;
1554 public static InstanceIdentifier<StateTunnelList> buildStateTunnelListId(StateTunnelListKey tlKey) {
1555 return InstanceIdentifier.builder(TunnelsState.class)
1556 .child(StateTunnelList.class, tlKey).build();
1559 public static Optional<InternalTunnel> getInternalTunnelFromDS(BigInteger srcDpn, BigInteger destDpn,
1560 Class<? extends TunnelTypeBase> type,
1561 DataBroker dataBroker) {
1562 InstanceIdentifier<InternalTunnel> pathLogicTunnel = InstanceIdentifier.create(TunnelList.class)
1563 .child(InternalTunnel.class,
1564 new InternalTunnelKey(destDpn, srcDpn, type));
1565 //TODO: need to be replaced by cached copy
1566 return ItmUtils.read(LogicalDatastoreType.CONFIGURATION, pathLogicTunnel, dataBroker);
1569 public static boolean isTunnelAggregationUsed(Class<? extends TunnelTypeBase> tunType) {
1570 return (ItmTunnelAggregationHelper.isTunnelAggregationEnabled()
1571 && (tunType.isAssignableFrom(TunnelTypeVxlan.class)
1572 || tunType.isAssignableFrom(TunnelTypeLogicalGroup.class)));
1575 public static List<TunnelOptions> buildTunnelOptions(TunnelEndPoints tep, ItmConfig itmConfig) {
1576 List<TunnelOptions> tunOptions = null;
1578 String tos = tep.getOptionTunnelTos();
1580 tos = itmConfig.getDefaultTunnelTos();
1582 /* populate tos option only if its not default value of 0 */
1583 if (tos != null && !tos.equals("0")) {
1584 tunOptions = new ArrayList<>(1);
1585 TunnelOptionsBuilder optionsBuilder = new TunnelOptionsBuilder();
1586 optionsBuilder.setKey(new TunnelOptionsKey("tos"));
1587 optionsBuilder.setTunnelOption("tos");
1588 optionsBuilder.setValue(tos);
1589 tunOptions.add(optionsBuilder.build());