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;
26 import org.apache.commons.lang3.StringUtils;
27 import org.apache.commons.net.util.SubnetUtils;
28 import org.apache.commons.net.util.SubnetUtils.SubnetInfo;
29 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
30 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
31 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
32 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
33 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
34 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
35 import org.opendaylight.genius.interfacemanager.globals.IfmConstants;
36 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
37 import org.opendaylight.genius.itm.api.IITMProvider;
38 import org.opendaylight.genius.itm.confighelpers.HwVtep;
39 import org.opendaylight.genius.itm.confighelpers.ItmTunnelAggregationHelper;
40 import org.opendaylight.genius.itm.globals.ITMConstants;
41 import org.opendaylight.genius.mdsalutil.ActionInfo;
42 import org.opendaylight.genius.mdsalutil.FlowEntity;
43 import org.opendaylight.genius.mdsalutil.InstructionInfo;
44 import org.opendaylight.genius.mdsalutil.MDSALUtil;
45 import org.opendaylight.genius.mdsalutil.MatchInfo;
46 import org.opendaylight.genius.mdsalutil.NwConstants;
47 import org.opendaylight.genius.mdsalutil.actions.ActionPuntToController;
48 import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
49 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
50 import org.opendaylight.genius.mdsalutil.matches.MatchTunnelId;
51 import org.opendaylight.genius.utils.cache.DataStoreCache;
52 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel;
53 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
54 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
55 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType;
56 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
57 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
58 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
59 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
60 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInput;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInputBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlanBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnel;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnelBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefs;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefsBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelMonitoringTypeBase;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelMonitoringTypeBfd;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeGre;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeLogicalGroup;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeMplsOverGre;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.interfaces._interface.NodeIdentifier;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.interfaces._interface.NodeIdentifierBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.interfaces._interface.NodeIdentifierKey;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.tunnel.optional.params.TunnelOptions;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.tunnel.optional.params.TunnelOptionsBuilder;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.tunnel.optional.params.TunnelOptionsKey;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.ItmConfig;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.TunnelMonitorInterval;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.TunnelMonitorIntervalBuilder;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.TunnelMonitorParams;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.TunnelMonitorParamsBuilder;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.VtepConfigSchemas;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.VtepIpPools;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.VtepConfigSchema;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.VtepConfigSchemaBuilder;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.VtepConfigSchemaKey;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.vtep.config.schema.DpnIds;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.vtep.config.schema.DpnIdsBuilder;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.vtep.config.schema.DpnIdsKey;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.ip.pools.VtepIpPool;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.ip.pools.VtepIpPoolKey;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpointsBuilder;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.ExternalTunnelList;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeBase;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeExternal;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeHwvtep;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeInternal;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelList;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelOperStatus;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelsState;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoBuilder;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoKey;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPointsBuilder;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPointsKey;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.tunnel.end.points.TzMembership;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.tunnel.end.points.TzMembershipBuilder;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnel;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnelBuilder;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnelKey;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnel;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnelBuilder;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnelKey;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelList;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelListBuilder;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelListKey;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.state.tunnel.list.DstInfoBuilder;
129 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.state.tunnel.list.SrcInfoBuilder;
130 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.DcGatewayIpList;
131 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZones;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.dc.gateway.ip.list.DcGatewayIp;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TepsNotHostedInTransportZone;
134 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TepsNotHostedInTransportZoneKey;
135 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZone;
136 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZoneKey;
137 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.Subnets;
138 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.Vteps;
139 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
140 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
141 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
142 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
143 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
144 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
145 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
146 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
147 import org.opendaylight.yangtools.yang.binding.DataObject;
148 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
149 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
150 import org.opendaylight.yangtools.yang.common.RpcResult;
151 import org.slf4j.Logger;
152 import org.slf4j.LoggerFactory;
154 public class ItmUtils {
156 public static final String DUMMY_IP_ADDRESS = "0.0.0.0";
157 public static final String TUNNEL_TYPE_VXLAN = "VXLAN";
158 public static final String TUNNEL_TYPE_GRE = "GRE";
159 public static final String TUNNEL = "tun";
160 public static final IpPrefix DUMMY_IP_PREFIX = new IpPrefix(ITMConstants.DUMMY_PREFIX.toCharArray());
161 public static ItmCache itmCache = new ItmCache();
163 private static final Logger LOG = LoggerFactory.getLogger(ItmUtils.class);
165 public static final ImmutableMap<String, Class<? extends TunnelTypeBase>>
167 new ImmutableMap.Builder<String, Class<? extends TunnelTypeBase>>()
168 .put(ITMConstants.TUNNEL_TYPE_GRE, TunnelTypeGre.class)
169 .put(ITMConstants.TUNNEL_TYPE_MPLSoGRE, TunnelTypeMplsOverGre.class)
170 .put(ITMConstants.TUNNEL_TYPE_VXLAN, TunnelTypeVxlan.class)
173 public static final FutureCallback<Void> DEFAULT_CALLBACK = new FutureCallback<Void>() {
175 public void onSuccess(Void result) {
176 LOG.debug("Success in Datastore write operation");
180 public void onFailure(Throwable error) {
181 LOG.error("Error in Datastore write operation", error);
185 @SuppressWarnings("checkstyle:IllegalCatch")
186 public static <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType,
187 InstanceIdentifier<T> path, DataBroker broker) {
188 try (ReadOnlyTransaction tx = broker.newReadOnlyTransaction()) {
189 return tx.read(datastoreType, path).get();
190 } catch (Exception e) {
191 throw new RuntimeException(e);
195 public static <T extends DataObject> void asyncWrite(LogicalDatastoreType datastoreType,
196 InstanceIdentifier<T> path, T data, DataBroker broker,
197 FutureCallback<Void> callback) {
198 WriteTransaction tx = broker.newWriteOnlyTransaction();
199 tx.put(datastoreType, path, data, true);
200 Futures.addCallback(tx.submit(), callback);
203 public static <T extends DataObject> void asyncUpdate(LogicalDatastoreType datastoreType,
204 InstanceIdentifier<T> path, T data, DataBroker broker,
205 FutureCallback<Void> callback) {
206 WriteTransaction tx = broker.newWriteOnlyTransaction();
207 tx.merge(datastoreType, path, data, true);
208 Futures.addCallback(tx.submit(), callback);
211 public static <T extends DataObject> void asyncDelete(LogicalDatastoreType datastoreType,
212 InstanceIdentifier<T> path, DataBroker broker,
213 FutureCallback<Void> callback) {
214 WriteTransaction tx = broker.newWriteOnlyTransaction();
215 tx.delete(datastoreType, path);
216 Futures.addCallback(tx.submit(), callback);
219 public static <T extends DataObject> void asyncBulkRemove(final DataBroker broker,
220 final LogicalDatastoreType datastoreType,
221 List<InstanceIdentifier<T>> pathList,
222 FutureCallback<Void> callback) {
223 if (!pathList.isEmpty()) {
224 WriteTransaction tx = broker.newWriteOnlyTransaction();
225 for (InstanceIdentifier<T> path : pathList) {
226 tx.delete(datastoreType, path);
228 Futures.addCallback(tx.submit(), callback);
232 public static String getInterfaceName(final BigInteger datapathid, final String portName, final Integer vlanId) {
233 return String.format("%s:%s:%s", datapathid, portName, vlanId);
236 public static BigInteger getDpnIdFromInterfaceName(String interfaceName) {
237 String[] dpnStr = interfaceName.split(":");
238 BigInteger dpnId = new BigInteger(dpnStr[0]);
242 public static String getTrunkInterfaceName(IdManagerService idManager, String parentInterfaceName,
243 String localHostName, String remoteHostName, String tunnelType) {
244 String tunnelTypeStr;
245 if (tunnelType.contains("TunnelTypeGre")) {
246 tunnelTypeStr = ITMConstants.TUNNEL_TYPE_GRE;
247 } else if (tunnelType.contains("TunnelTypeLogicalGroup")) {
248 tunnelTypeStr = ITMConstants.TUNNEL_TYPE_LOGICAL_GROUP_VXLAN;
250 tunnelTypeStr = ITMConstants.TUNNEL_TYPE_VXLAN;
252 String trunkInterfaceName = String.format("%s:%s:%s:%s", parentInterfaceName, localHostName,
253 remoteHostName, tunnelTypeStr);
254 LOG.trace("trunk interface name is {}", trunkInterfaceName);
255 trunkInterfaceName = String.format("%s%s", TUNNEL, getUniqueIdString(trunkInterfaceName));
256 return trunkInterfaceName;
259 public static void releaseIdForTrunkInterfaceName(IdManagerService idManager, String parentInterfaceName,
260 String localHostName, String remoteHostName, String tunnelType) {
261 String tunnelTypeStr;
262 if (tunnelType.contains("TunnelTypeGre")) {
263 tunnelTypeStr = ITMConstants.TUNNEL_TYPE_GRE;
265 tunnelTypeStr = ITMConstants.TUNNEL_TYPE_VXLAN;
267 String trunkInterfaceName = String.format("%s:%s:%s:%s", parentInterfaceName, localHostName,
268 remoteHostName, tunnelTypeStr);
269 LOG.trace("Releasing Id for trunkInterface - {}", trunkInterfaceName);
270 //releaseId(idManager, trunkInterfaceName) ;
273 public static String getLogicalTunnelGroupName(BigInteger srcDpnId, BigInteger destDpnId) {
274 String tunnelTypeStr = ITMConstants.TUNNEL_TYPE_LOGICAL_GROUP_VXLAN;
275 String groupName = String.format("%s:%s:%s", srcDpnId.toString(), destDpnId.toString(), tunnelTypeStr);
276 LOG.trace("logical tunnel group name is {}", groupName);
277 groupName = String.format("%s%s", TUNNEL, getUniqueIdString(groupName));
281 public static InetAddress getInetAddressFromIpAddress(IpAddress ip) {
282 return InetAddresses.forString(ip.getIpv4Address().getValue());
285 public static InstanceIdentifier<DPNTEPsInfo> getDpnTepInstance(BigInteger dpIdKey) {
286 InstanceIdentifier.InstanceIdentifierBuilder<DPNTEPsInfo> dpnTepInfoBuilder =
287 InstanceIdentifier.builder(DpnEndpoints.class).child(DPNTEPsInfo.class,
288 new DPNTEPsInfoKey(dpIdKey));
289 InstanceIdentifier<DPNTEPsInfo> dpnInfo = dpnTepInfoBuilder.build();
293 public static DPNTEPsInfo createDPNTepInfo(BigInteger dpId, List<TunnelEndPoints> endpoints) {
294 return new DPNTEPsInfoBuilder().setKey(new DPNTEPsInfoKey(dpId)).setTunnelEndPoints(endpoints).build();
297 public static TunnelEndPoints createTunnelEndPoints(BigInteger dpnId, IpAddress ipAddress, String portName,
298 boolean isOfTunnel, int vlanId, IpPrefix prefix,
299 IpAddress gwAddress, List<TzMembership> zones,
300 Class<? extends TunnelTypeBase> tunnelType,
302 // when Interface Mgr provides support to take in Dpn Id
303 return new TunnelEndPointsBuilder().setKey(new TunnelEndPointsKey(ipAddress, portName,tunnelType, vlanId))
304 .setSubnetMask(prefix).setGwIpAddress(gwAddress).setTzMembership(zones)
305 .setOptionOfTunnel(isOfTunnel).setInterfaceName(ItmUtils.getInterfaceName(dpnId, portName, vlanId))
306 .setTunnelType(tunnelType)
307 .setOptionTunnelTos(tos)
311 public static DpnEndpoints createDpnEndpoints(List<DPNTEPsInfo> dpnTepInfo) {
312 return new DpnEndpointsBuilder().setDPNTEPsInfo(dpnTepInfo).build();
315 public static InstanceIdentifier<Interface> buildId(String interfaceName) {
316 InstanceIdentifierBuilder<Interface> idBuilder =
317 InstanceIdentifier.builder(Interfaces.class).child(Interface.class, new InterfaceKey(interfaceName));
318 InstanceIdentifier<Interface> id = idBuilder.build();
322 public static InstanceIdentifier<IfTunnel> buildTunnelId(String ifName) {
323 InstanceIdentifier<IfTunnel> tunnelInstIdentifier = InstanceIdentifier.builder(Interfaces.class)
324 .child(Interface.class, new InterfaceKey(ifName)).augmentation(IfTunnel.class).build();
325 return tunnelInstIdentifier;
328 public static Interface buildLogicalTunnelInterface(BigInteger dpn, String ifName, String desc, boolean enabled) {
329 InterfaceBuilder builder = new InterfaceBuilder().setKey(new InterfaceKey(ifName)).setName(ifName)
330 .setDescription(desc).setEnabled(enabled).setType(Tunnel.class);
331 ParentRefs parentRefs = new ParentRefsBuilder().setDatapathNodeIdentifier(dpn).build();
332 builder.addAugmentation(ParentRefs.class, parentRefs);
334 IfTunnel tunnel = new IfTunnelBuilder().setTunnelDestination(new IpAddress("0.0.0.0".toCharArray()))
335 .setTunnelSource(new IpAddress("0.0.0.0".toCharArray())).setInternal(true).setMonitorEnabled(false)
336 .setTunnelInterfaceType(TunnelTypeLogicalGroup.class).setTunnelRemoteIpFlow(false).build();
337 builder.addAugmentation(IfTunnel.class, tunnel);
338 return builder.build();
341 public static Interface buildTunnelInterface(BigInteger dpn, String ifName, String desc, boolean enabled,
342 Class<? extends TunnelTypeBase> tunType, IpAddress localIp,
343 IpAddress remoteIp, IpAddress gatewayIp, Integer vlanId,
344 boolean internal, Boolean monitorEnabled,
345 Class<? extends TunnelMonitoringTypeBase> monitorProtocol,
346 Integer monitorInterval, boolean useOfTunnel,
347 List<TunnelOptions> tunOptions) {
349 return buildTunnelInterface(dpn, ifName, desc, enabled, tunType, localIp, remoteIp, gatewayIp, vlanId,
350 internal, monitorEnabled, monitorProtocol, monitorInterval, useOfTunnel, null,
354 public static Interface buildTunnelInterface(BigInteger dpn, String ifName, String desc, boolean enabled,
355 Class<? extends TunnelTypeBase> tunType, IpAddress localIp,
356 IpAddress remoteIp, IpAddress gatewayIp, Integer vlanId,
357 boolean internal, Boolean monitorEnabled,
358 Class<? extends TunnelMonitoringTypeBase> monitorProtocol,
359 Integer monitorInterval, boolean useOfTunnel, String parentIfaceName,
360 List<TunnelOptions> tunnelOptions) {
361 InterfaceBuilder builder = new InterfaceBuilder().setKey(new InterfaceKey(ifName)).setName(ifName)
362 .setDescription(desc).setEnabled(enabled).setType(Tunnel.class);
363 ParentRefs parentRefs =
364 new ParentRefsBuilder().setDatapathNodeIdentifier(dpn).setParentInterface(parentIfaceName).build();
365 builder.addAugmentation(ParentRefs.class, parentRefs);
366 Long monitoringInterval = null;
368 IfL2vlan l2vlan = new IfL2vlanBuilder().setVlanId(new VlanId(vlanId)).build();
369 builder.addAugmentation(IfL2vlan.class, l2vlan);
371 LOG.debug("buildTunnelInterface: monitorProtocol = {} and monitorInterval = {}",
372 monitorProtocol.getName(),monitorInterval);
374 if (monitorInterval != null) {
375 monitoringInterval = monitorInterval.longValue();
378 IfTunnel tunnel = new IfTunnelBuilder().setTunnelDestination(remoteIp).setTunnelGateway(gatewayIp)
379 .setTunnelSource(localIp).setTunnelInterfaceType(tunType).setInternal(internal)
380 .setMonitorEnabled(monitorEnabled).setMonitorProtocol(monitorProtocol)
381 .setMonitorInterval(monitoringInterval).setTunnelRemoteIpFlow(useOfTunnel)
382 .setTunnelOptions(tunnelOptions)
384 builder.addAugmentation(IfTunnel.class, tunnel);
385 return builder.build();
388 public static Interface buildHwTunnelInterface(String tunnelIfName, String desc, boolean enabled, String topoId,
389 String nodeId, Class<? extends TunnelTypeBase> tunType,
390 IpAddress srcIp, IpAddress destIp, IpAddress gwIp,
391 Boolean monitorEnabled,
392 Class<? extends TunnelMonitoringTypeBase> monitorProtocol,
393 Integer monitorInterval) {
394 InterfaceBuilder builder = new InterfaceBuilder().setKey(new InterfaceKey(tunnelIfName))
395 .setName(tunnelIfName).setDescription(desc).setEnabled(enabled).setType(Tunnel.class);
396 List<NodeIdentifier> nodeIds = new ArrayList<>();
397 NodeIdentifier hwNode = new NodeIdentifierBuilder().setKey(new NodeIdentifierKey(topoId))
398 .setTopologyId(topoId).setNodeId(nodeId).build();
400 ParentRefs parent = new ParentRefsBuilder().setNodeIdentifier(nodeIds).build();
401 builder.addAugmentation(ParentRefs.class, parent);
402 Long monitoringInterval = (long) ITMConstants.DEFAULT_MONITOR_INTERVAL;
403 Boolean monitoringEnabled = true;
404 Class<? extends TunnelMonitoringTypeBase> monitoringProtocol = ITMConstants.DEFAULT_MONITOR_PROTOCOL;
405 if (monitoringInterval != null) {
406 monitoringInterval = monitorInterval.longValue();
408 if (monitorEnabled != null) {
409 monitoringEnabled = monitorEnabled;
411 if (monitorProtocol != null) {
412 monitoringProtocol = monitorProtocol;
414 IfTunnel tunnel = new IfTunnelBuilder().setTunnelDestination(destIp).setTunnelGateway(gwIp)
415 .setTunnelSource(srcIp).setMonitorEnabled(monitoringEnabled).setMonitorProtocol(monitorProtocol)
416 .setMonitorInterval(100L).setTunnelInterfaceType(tunType).setInternal(false).build();
417 builder.addAugmentation(IfTunnel.class, tunnel);
418 LOG.trace("iftunnel {} built from hwvtep {} ", tunnel, nodeId);
419 return builder.build();
423 public static InternalTunnel buildInternalTunnel(BigInteger srcDpnId, BigInteger dstDpnId,
424 Class<? extends TunnelTypeBase> tunType,
425 String trunkInterfaceName) {
426 InternalTunnel tnl = new InternalTunnelBuilder().setKey(new InternalTunnelKey(dstDpnId, srcDpnId, tunType))
427 .setDestinationDPN(dstDpnId)
428 .setSourceDPN(srcDpnId).setTransportType(tunType)
429 .setTunnelInterfaceNames(Collections.singletonList(trunkInterfaceName)).build();
433 public static ExternalTunnel buildExternalTunnel(String srcNode, String dstNode,
434 Class<? extends TunnelTypeBase> tunType,
435 String trunkInterfaceName) {
436 ExternalTunnel extTnl = new ExternalTunnelBuilder().setKey(
437 new ExternalTunnelKey(dstNode, srcNode, tunType))
438 .setSourceDevice(srcNode).setDestinationDevice(dstNode)
439 .setTunnelInterfaceName(trunkInterfaceName)
440 .setTransportType(tunType).build();
444 public static List<DPNTEPsInfo> getTunnelMeshInfo(DataBroker dataBroker) {
445 List<DPNTEPsInfo> dpnTEPs = null ;
447 // Read the Mesh Information from Cache if not read from the DS
448 dpnTEPs = getTunnelMeshInfo() ;
449 if (dpnTEPs != null) {
453 // Read the EndPoint Info from the operational database
454 InstanceIdentifierBuilder<DpnEndpoints> depBuilder = InstanceIdentifier.builder(DpnEndpoints.class);
455 InstanceIdentifier<DpnEndpoints> deps = depBuilder.build();
456 Optional<DpnEndpoints> dpnEps = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, deps, dataBroker);
457 if (dpnEps.isPresent()) {
458 DpnEndpoints tn = dpnEps.get();
459 dpnTEPs = tn.getDPNTEPsInfo();
460 LOG.debug("Read from CONFIGURATION datastore - No. of Dpns " , dpnTEPs.size());
462 LOG.debug("No Dpn information in CONFIGURATION datastore ");
467 // Reading the Mesh Information from Cache
468 public static List<DPNTEPsInfo> getTunnelMeshInfo() {
469 List<DPNTEPsInfo> dpnTepsInfo = null ;
470 List<Object> values = null ;
472 values = DataStoreCache.getValues(ITMConstants.DPN_TEPs_Info_CACHE_NAME);
473 if (values != null) {
474 dpnTepsInfo = new ArrayList<>() ;
475 for (Object value : values) {
476 dpnTepsInfo.add((DPNTEPsInfo)value) ;
482 public static int getUniqueId(IdManagerService idManager, String idKey) {
483 AllocateIdInput getIdInput = new AllocateIdInputBuilder()
484 .setPoolName(ITMConstants.ITM_IDPOOL_NAME)
485 .setIdKey(idKey).build();
488 Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
489 RpcResult<AllocateIdOutput> rpcResult = result.get();
490 if (rpcResult.isSuccessful()) {
491 return rpcResult.getResult().getIdValue().intValue();
493 LOG.warn("RPC Call to Get Unique Id returned with Errors {}", rpcResult.getErrors());
495 } catch (InterruptedException | ExecutionException e) {
496 LOG.warn("Exception when getting Unique Id",e);
501 public static String getUniqueIdString(String idKey) {
502 return UUID.nameUUIDFromBytes(idKey.getBytes()).toString().substring(0, 12).replace("-", "");
505 public static void releaseId(IdManagerService idManager, String idKey) {
506 ReleaseIdInput idInput =
507 new ReleaseIdInputBuilder().setPoolName(ITMConstants.ITM_IDPOOL_NAME).setIdKey(idKey).build();
509 Future<RpcResult<Void>> result = idManager.releaseId(idInput);
510 RpcResult<Void> rpcResult = result.get();
511 if (!rpcResult.isSuccessful()) {
512 LOG.warn("RPC Call to Get Unique Id returned with Errors {}", rpcResult.getErrors());
514 } catch (InterruptedException | ExecutionException e) {
515 LOG.warn("Exception when getting Unique Id for key {}", idKey, e);
519 public static List<DPNTEPsInfo> getDpnTepListFromDpnId(DataBroker dataBroker, List<BigInteger> dpnIds) {
520 List<DPNTEPsInfo> meshedDpnList = getTunnelMeshInfo(dataBroker) ;
521 List<DPNTEPsInfo> cfgDpnList = new ArrayList<>();
522 if (null != meshedDpnList) {
523 for (BigInteger dpnId : dpnIds) {
524 for (DPNTEPsInfo teps : meshedDpnList) {
525 if (dpnId.equals(teps.getDPNID())) {
526 cfgDpnList.add(teps);
534 @SuppressWarnings("checkstyle:IllegalCatch")
535 public static void setUpOrRemoveTerminatingServiceTable(BigInteger dpnId, IMdsalApiManager mdsalManager,
537 String logmsg = addFlag ? "Installing" : "Removing";
538 LOG.trace("{}PUNT to Controller flow in DPN {} ", logmsg, dpnId);
539 List<ActionInfo> listActionInfo = new ArrayList<>();
540 listActionInfo.add(new ActionPuntToController());
543 List<MatchInfo> mkMatches = new ArrayList<>();
545 mkMatches.add(new MatchTunnelId(BigInteger.valueOf(ITMConstants.LLDP_SERVICE_ID)));
547 List<InstructionInfo> mkInstructions = new ArrayList<>();
548 mkInstructions.add(new InstructionApplyActions(listActionInfo));
550 FlowEntity terminatingServiceTableFlowEntity = MDSALUtil
551 .buildFlowEntity(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE,
552 getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE, ITMConstants.LLDP_SERVICE_ID),
553 5, String.format("%s:%d","ITM Flow Entry ", ITMConstants.LLDP_SERVICE_ID), 0, 0,
554 ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(ITMConstants.LLDP_SERVICE_ID)),
555 mkMatches, mkInstructions);
557 mdsalManager.installFlow(terminatingServiceTableFlowEntity);
559 mdsalManager.removeFlow(terminatingServiceTableFlowEntity);
561 } catch (Exception e) {
562 LOG.error("Error while setting up Table 36 for {}", dpnId, e);
566 private static String getFlowRef(long termSvcTable, int svcId) {
567 return String.valueOf(termSvcTable) + svcId;
570 public static InstanceIdentifier<VtepConfigSchema> getVtepConfigSchemaIdentifier(String schemaName) {
571 return InstanceIdentifier.builder(VtepConfigSchemas.class)
572 .child(VtepConfigSchema.class, new VtepConfigSchemaKey(schemaName)).build();
575 public static InstanceIdentifier<VtepConfigSchema> getVtepConfigSchemaIdentifier() {
576 return InstanceIdentifier.builder(VtepConfigSchemas.class).child(VtepConfigSchema.class).build();
579 public static InstanceIdentifier<VtepConfigSchemas> getVtepConfigSchemasIdentifier() {
580 return InstanceIdentifier.builder(VtepConfigSchemas.class).build();
583 public static InstanceIdentifier<VtepIpPool> getVtepIpPoolIdentifier(String subnetCidr) {
584 return InstanceIdentifier.builder(VtepIpPools.class).child(VtepIpPool.class, new VtepIpPoolKey(subnetCidr))
588 public static VtepConfigSchema validateForAddVtepConfigSchema(VtepConfigSchema schema,
589 List<VtepConfigSchema> existingSchemas) {
590 VtepConfigSchema validSchema = validateVtepConfigSchema(schema);
591 for (VtepConfigSchema existingSchema : emptyIfNull(existingSchemas)) {
592 if (!StringUtils.equalsIgnoreCase(schema.getSchemaName(), existingSchema.getSchemaName())
593 && schema.getSubnet().equals(existingSchema.getSubnet())) {
594 String subnetCidr = getSubnetCidrAsString(schema.getSubnet());
595 Preconditions.checkArgument(false, "VTEP schema with subnet [" + subnetCidr
596 + "] already exists. Multiple VTEP schemas with same subnet is not allowed.");
599 if (isNotEmpty(getDpnIdList(validSchema.getDpnIds()))) {
600 String tzone = validSchema.getTransportZoneName();
601 List<BigInteger> lstDpns = getConflictingDpnsAlreadyConfiguredWithTz(validSchema.getSchemaName(), tzone,
602 getDpnIdList(validSchema.getDpnIds()), existingSchemas);
603 if (!lstDpns.isEmpty()) {
604 Preconditions.checkArgument(false, "DPN's " + lstDpns + " already configured for transport zone "
605 + tzone + ". Only one end point per transport Zone per Dpn is allowed.");
607 if (schema.getTunnelType().equals(TunnelTypeGre.class)) {
608 validateForSingleGreTep(validSchema.getSchemaName(), getDpnIdList(validSchema.getDpnIds()),
615 private static void validateForSingleGreTep(String schemaName, List<BigInteger> lstDpnsForAdd,
616 List<VtepConfigSchema> existingSchemas) {
617 for (VtepConfigSchema existingSchema : emptyIfNull(existingSchemas)) {
618 if (TunnelTypeGre.class.equals(existingSchema.getTunnelType())
619 && !StringUtils.equalsIgnoreCase(schemaName, existingSchema.getSchemaName())) {
620 List<BigInteger> lstConflictingDpns = new ArrayList<>(getDpnIdList(existingSchema.getDpnIds()));
621 lstConflictingDpns.retainAll(emptyIfNull(lstDpnsForAdd));
622 if (!lstConflictingDpns.isEmpty()) {
623 String errMsg = "DPN's " + lstConflictingDpns
624 + " already configured with GRE TEP. Mutiple GRE TEP's on a single DPN are not allowed.";
625 Preconditions.checkArgument(false, errMsg);
631 public static VtepConfigSchema validateVtepConfigSchema(VtepConfigSchema schema) {
632 Preconditions.checkNotNull(schema);
633 Preconditions.checkArgument(StringUtils.isNotBlank(schema.getSchemaName()));
634 Preconditions.checkArgument(StringUtils.isNotBlank(schema.getPortName()));
635 Preconditions.checkArgument(schema.getVlanId() >= 0 && schema.getVlanId() < 4095,
636 "Invalid VLAN ID, range (0-4094)");
637 Preconditions.checkArgument(StringUtils.isNotBlank(schema.getTransportZoneName()));
638 Preconditions.checkNotNull(schema.getSubnet());
639 String subnetCidr = getSubnetCidrAsString(schema.getSubnet());
640 SubnetUtils subnetUtils = new SubnetUtils(subnetCidr);
641 IpAddress gatewayIp = schema.getGatewayIp();
642 if (gatewayIp != null) {
643 String strGatewayIp = String.valueOf(gatewayIp.getValue());
644 if (!strGatewayIp.equals(ITMConstants.DUMMY_IP_ADDRESS) && !subnetUtils.getInfo().isInRange(strGatewayIp)) {
645 Preconditions.checkArgument(false, "Gateway IP address " + strGatewayIp
646 + " is not in subnet range " + subnetCidr);
649 ItmUtils.getExcludeIpAddresses(schema.getExcludeIpFilter(), subnetUtils.getInfo());
650 return new VtepConfigSchemaBuilder(schema).setTunnelType(schema.getTunnelType()).build();
653 public static String validateTunnelType(String tunnelType) {
654 if (tunnelType == null) {
655 tunnelType = ITMConstants.TUNNEL_TYPE_VXLAN;
657 tunnelType = StringUtils.upperCase(tunnelType);
658 String error = "Invalid tunnel type. Valid values: "
659 + ITMConstants.TUNNEL_TYPE_VXLAN + " | " + ITMConstants.TUNNEL_TYPE_GRE;
660 Preconditions.checkArgument(ITMConstants.TUNNEL_TYPE_VXLAN.equals(tunnelType)
661 || ITMConstants.TUNNEL_TYPE_GRE.equals(tunnelType), error);
666 private static List<BigInteger> getConflictingDpnsAlreadyConfiguredWithTz(String schemaName, String tzone,
667 List<BigInteger> lstDpns,
668 List<VtepConfigSchema> existingSchemas) {
669 List<BigInteger> lstConflictingDpns = new ArrayList<>();
670 for (VtepConfigSchema schema : emptyIfNull(existingSchemas)) {
671 if (!StringUtils.equalsIgnoreCase(schemaName, schema.getSchemaName())
672 && StringUtils.equals(schema.getTransportZoneName(), tzone)) {
673 lstConflictingDpns = new ArrayList<>(getDpnIdList(schema.getDpnIds()));
674 lstConflictingDpns.retainAll(lstDpns);
675 if (!lstConflictingDpns.isEmpty()) {
680 return lstConflictingDpns;
683 public static VtepConfigSchema constructVtepConfigSchema(String schemaName, String portName, Integer vlanId,
684 String subnetMask, String gatewayIp, String transportZone,
685 String tunnelType, List<BigInteger> dpnIds,
686 String excludeIpFilter) {
687 IpAddress gatewayIpObj = StringUtils.isBlank(gatewayIp) ? null : new IpAddress(gatewayIp.toCharArray());
688 IpPrefix subnet = StringUtils.isBlank(subnetMask) ? null : new IpPrefix(subnetMask.toCharArray());
689 Class<? extends TunnelTypeBase> tunType ;
690 if (tunnelType.equals(ITMConstants.TUNNEL_TYPE_VXLAN)) {
691 tunType = TunnelTypeVxlan.class ;
693 tunType = TunnelTypeGre.class ;
695 VtepConfigSchemaBuilder schemaBuilder = new VtepConfigSchemaBuilder().setSchemaName(schemaName)
696 .setPortName(portName).setVlanId(vlanId).setSubnet(subnet).setGatewayIp(gatewayIpObj)
697 .setTransportZoneName(transportZone).setTunnelType(tunType).setDpnIds(getDpnIdsListFromBigInt(dpnIds))
698 .setExcludeIpFilter(excludeIpFilter);
699 return schemaBuilder.build();
702 public static List<IpAddress> getExcludeIpAddresses(String excludeIpFilter, SubnetInfo subnetInfo) {
703 final List<IpAddress> lstIpAddress = new ArrayList<>();
704 if (StringUtils.isBlank(excludeIpFilter)) {
707 final String[] arrIps = StringUtils.split(excludeIpFilter, ',');
708 for (String ip : arrIps) {
709 if (StringUtils.countMatches(ip, "-") == 1) {
710 final String[] arrIpRange = StringUtils.split(ip, '-');
711 String strStartIp = StringUtils.trim(arrIpRange[0]);
712 String strEndIp = StringUtils.trim(arrIpRange[1]);
713 Preconditions.checkArgument(InetAddresses.isInetAddress(strStartIp),
714 "Invalid exclude IP filter: invalid IP address value " + strStartIp);
715 Preconditions.checkArgument(InetAddresses.isInetAddress(strEndIp),
716 "Invalid exclude IP filter: invalid IP address value " + strEndIp);
717 Preconditions.checkArgument(subnetInfo.isInRange(strStartIp),
718 "Invalid exclude IP filter: IP address [" + strStartIp
719 + "] not in subnet range " + subnetInfo.getCidrSignature());
720 Preconditions.checkArgument(subnetInfo.isInRange(strEndIp),
721 "Invalid exclude IP filter: IP address [" + strEndIp
722 + "] not in subnet range " + subnetInfo.getCidrSignature());
723 int startIp = subnetInfo.asInteger(strStartIp);
724 int endIp = subnetInfo.asInteger(strEndIp);
726 Preconditions.checkArgument(startIp < endIp,
727 "Invalid exclude IP filter: Invalid range [" + ip + "] ");
728 for (int iter = startIp; iter <= endIp; iter++) {
729 String ipAddress = ipFormat(toIpArray(iter));
730 validateAndAddIpAddressToList(subnetInfo, lstIpAddress, ipAddress);
733 validateAndAddIpAddressToList(subnetInfo, lstIpAddress, ip);
739 private static void validateAndAddIpAddressToList(SubnetInfo subnetInfo, final List<IpAddress> lstIpAddress,
741 String ip = StringUtils.trim(ipAddress);
742 Preconditions.checkArgument(InetAddresses.isInetAddress(ip),
743 "Invalid exclude IP filter: invalid IP address value " + ip);
744 Preconditions.checkArgument(subnetInfo.isInRange(ip),
745 "Invalid exclude IP filter: IP address [" + ip + "] not in subnet range "
746 + subnetInfo.getCidrSignature());
747 lstIpAddress.add(new IpAddress(ip.toCharArray()));
750 private static int[] toIpArray(int val) {
751 int[] ret = new int[4];
752 for (int iter = 3; iter >= 0; --iter) {
753 ret[iter] |= val >>> 8 * (3 - iter) & 0xff;
758 private static String ipFormat(int[] octets) {
759 StringBuilder str = new StringBuilder();
760 for (int iter = 0; iter < octets.length; ++iter) {
761 str.append(octets[iter]);
762 if (iter != octets.length - 1) {
766 return str.toString();
769 public static VtepConfigSchema validateForUpdateVtepSchema(String schemaName, List<BigInteger> lstDpnsForAdd,
770 List<BigInteger> lstDpnsForDelete,
771 IITMProvider itmProvider) {
772 Preconditions.checkArgument(StringUtils.isNotBlank(schemaName));
773 if ((lstDpnsForAdd == null || lstDpnsForAdd.isEmpty())
774 && (lstDpnsForDelete == null || lstDpnsForDelete.isEmpty())) {
775 Preconditions.checkArgument(false,
776 "DPN ID list for add | delete is null or empty in schema " + schemaName);
778 VtepConfigSchema schema = itmProvider.getVtepConfigSchema(schemaName);
779 if (schema == null) {
780 Preconditions.checkArgument(false, "Specified VTEP Schema [" + schemaName
781 + "] doesn't exists!");
783 List<BigInteger> existingDpnIds = getDpnIdList(schema.getDpnIds());
784 if (isNotEmpty(lstDpnsForAdd)) {
785 // if (isNotEmpty(existingDpnIds)) {
786 List<BigInteger> lstAlreadyExistingDpns = new ArrayList<>(existingDpnIds);
787 lstAlreadyExistingDpns.retainAll(lstDpnsForAdd);
788 Preconditions.checkArgument(lstAlreadyExistingDpns.isEmpty(),
789 "DPN ID's " + lstAlreadyExistingDpns
790 + " already exists in VTEP schema [" + schemaName + "]");
792 if (schema.getTunnelType().equals(TunnelTypeGre.class)) {
793 validateForSingleGreTep(schema.getSchemaName(), lstDpnsForAdd, itmProvider.getAllVtepConfigSchemas());
796 if (isNotEmpty(lstDpnsForDelete)) {
797 if (existingDpnIds == null || existingDpnIds.isEmpty()) {
798 String builder = "DPN ID's " + lstDpnsForDelete
799 + " specified for delete from VTEP schema [" + schemaName
800 + "] are not configured in the schema.";
801 Preconditions.checkArgument(false, builder);
802 } else if (!existingDpnIds.containsAll(lstDpnsForDelete)) {
803 List<BigInteger> lstConflictingDpns = new ArrayList<>(lstDpnsForDelete);
804 lstConflictingDpns.removeAll(existingDpnIds);
805 String builder = "DPN ID's " + lstConflictingDpns
806 + " specified for delete from VTEP schema [" + schemaName
807 + "] are not configured in the schema.";
808 Preconditions.checkArgument(false, builder);
814 public static String getSubnetCidrAsString(IpPrefix subnet) {
815 return subnet == null ? StringUtils.EMPTY : String.valueOf(subnet.getValue());
818 public static <T> List<T> emptyIfNull(List<T> list) {
819 return list == null ? Collections.emptyList() : list;
822 public static <T> boolean isEmpty(Collection<T> collection) {
823 return collection == null || collection.isEmpty();
826 public static <T> boolean isNotEmpty(Collection<T> collection) {
827 return !isEmpty(collection);
830 public static HwVtep createHwVtepObject(String topoId, String nodeId, IpAddress ipAddress, IpPrefix ipPrefix,
831 IpAddress gatewayIP, int vlanID,
832 Class<? extends TunnelTypeBase> tunneltype, TransportZone transportZone) {
833 HwVtep hwVtep = new HwVtep();
834 hwVtep.setGatewayIP(gatewayIP);
835 hwVtep.setHwIp(ipAddress);
836 hwVtep.setIpPrefix(ipPrefix);
837 hwVtep.setNodeId(nodeId);
838 hwVtep.setTopoId(topoId);
839 hwVtep.setTransportZone(transportZone.getZoneName());
840 hwVtep.setTunnelType(tunneltype);
841 hwVtep.setVlanID(vlanID);
845 public static String getHwParentIf(String topoId, String srcNodeid) {
846 return String.format("%s:%s", topoId, srcNodeid);
849 public static <T extends DataObject> void syncWrite(LogicalDatastoreType datastoreType,
850 InstanceIdentifier<T> path, T data, DataBroker broker) {
851 WriteTransaction tx = broker.newWriteOnlyTransaction();
852 tx.put(datastoreType, path, data, true);
853 CheckedFuture<Void, TransactionCommitFailedException> futures = tx.submit();
856 } catch (InterruptedException | ExecutionException e) {
857 LOG.error("ITMUtils:SyncWrite , Error writing to datastore (path, data) : ({}, {})", path, data);
858 throw new RuntimeException(e.getMessage());
862 public static List<BigInteger> getDpnIdList(List<DpnIds> dpnIds) {
863 List<BigInteger> dpnList = new ArrayList<>() ;
864 for (DpnIds dpn : dpnIds) {
865 dpnList.add(dpn.getDPN()) ;
870 public static List<DpnIds> getDpnIdsListFromBigInt(List<BigInteger> dpnIds) {
871 List<DpnIds> dpnIdList = new ArrayList<>();
872 DpnIdsBuilder builder = new DpnIdsBuilder();
873 for (BigInteger dpnId : dpnIds) {
874 dpnIdList.add(builder.setKey(new DpnIdsKey(dpnId)).setDPN(dpnId).build());
879 public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
880 .interfaces.state.Interface> buildStateInterfaceId(String interfaceName) {
881 InstanceIdentifierBuilder<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
882 .interfaces.state.Interface> idBuilder = InstanceIdentifier.builder(InterfacesState.class)
883 .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
884 .interfaces.state.Interface.class,
885 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
886 .interfaces.state.InterfaceKey(interfaceName));
887 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
888 .interfaces.state.Interface> id = idBuilder.build();
892 public static Boolean readMonitoringStateFromCache(DataBroker dataBroker) {
893 InstanceIdentifier<TunnelMonitorParams> iid = InstanceIdentifier.create(TunnelMonitorParams.class);
894 TunnelMonitorParams tunnelMonitorParams = (TunnelMonitorParams) DataStoreCache
895 .get(ITMConstants.ITM_MONIRORING_PARAMS_CACHE_NAME,iid,"MonitorParams",dataBroker,true);
896 if (tunnelMonitorParams != null) {
897 return tunnelMonitorParams.isEnabled();
899 return ITMConstants.DEFAULT_MONITOR_ENABLED;
903 public static Integer readMonitorIntervalfromCache(DataBroker dataBroker) {
904 InstanceIdentifier<TunnelMonitorInterval> iid = InstanceIdentifier.create(TunnelMonitorInterval.class);
905 TunnelMonitorInterval tunnelMonitorIOptional = (TunnelMonitorInterval)DataStoreCache
906 .get(ITMConstants.ITM_MONIRORING_PARAMS_CACHE_NAME,iid,"Interval",dataBroker,true);
907 if (tunnelMonitorIOptional != null) {
908 return tunnelMonitorIOptional.getInterval();
914 public static Integer determineMonitorInterval(DataBroker dataBroker) {
915 Integer monitorInterval = ItmUtils.readMonitorIntervalfromCache(dataBroker);
916 LOG.debug("determineMonitorInterval: monitorInterval from DS = {}", monitorInterval);
917 if (monitorInterval == null) {
918 Class<? extends TunnelMonitoringTypeBase> monitorProtocol = determineMonitorProtocol(dataBroker);
919 if (monitorProtocol.isAssignableFrom(TunnelMonitoringTypeBfd.class)) {
920 monitorInterval = ITMConstants.BFD_DEFAULT_MONITOR_INTERVAL;
922 monitorInterval = ITMConstants.DEFAULT_MONITOR_INTERVAL;
925 LOG.debug("determineMonitorInterval: monitorInterval = {}", monitorInterval);
926 InstanceIdentifier<TunnelMonitorInterval> iid = InstanceIdentifier.builder(TunnelMonitorInterval.class).build();
927 TunnelMonitorInterval intervalBuilder = new TunnelMonitorIntervalBuilder().setInterval(monitorInterval).build();
928 ItmUtils.asyncUpdate(LogicalDatastoreType.OPERATIONAL,iid, intervalBuilder, dataBroker,
929 ItmUtils.DEFAULT_CALLBACK);
930 return monitorInterval;
933 public static List<String> getInternalTunnelInterfaces(DataBroker dataBroker) {
934 List<String> tunnelList = new ArrayList<>();
935 Collection<String> internalInterfaces = itmCache.getAllInternalInterfaces();
936 if (internalInterfaces == null) {
937 updateTunnelsCache(dataBroker);
938 internalInterfaces = itmCache.getAllInternalInterfaces();
940 LOG.debug("ItmUtils.getTunnelList Cache Internal Interfaces size: {} ", internalInterfaces.size());
941 if (internalInterfaces != null) {
942 tunnelList.addAll(internalInterfaces);
944 LOG.trace("ItmUtils.getTunnelList Internal: {}", tunnelList);
948 public static List<String> getTunnelsofTzone(List<HwVtep> hwVteps, String tzone, DataBroker dataBroker,
949 Boolean hwVtepsExist) {
951 List<String> tunnels = new ArrayList<>();
952 InstanceIdentifier<TransportZone> path = InstanceIdentifier.builder(TransportZones.class)
953 .child(TransportZone.class, new TransportZoneKey(tzone)).build();
954 Optional<TransportZone> transportZoneOptional =
955 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
956 if (transportZoneOptional.isPresent()) {
957 TransportZone transportZone = transportZoneOptional.get();
958 Class<? extends TunnelTypeBase> tunType = transportZone.getTunnelType();
959 if (transportZone.getSubnets() != null && !transportZone.getSubnets().isEmpty()) {
960 for (Subnets sub : transportZone.getSubnets()) {
961 if (sub.getVteps() != null && !sub.getVteps().isEmpty()) {
962 for (Vteps vtepLocal : sub.getVteps()) {
963 for (Vteps vtepRemote : sub.getVteps()) {
964 if (!vtepLocal.equals(vtepRemote)) {
965 InternalTunnelKey key = new InternalTunnelKey(vtepRemote.getDpnId(),
966 vtepLocal.getDpnId(), tunType);
967 InstanceIdentifier<InternalTunnel> intIID =
968 InstanceIdentifier.builder(TunnelList.class)
969 .child(InternalTunnel.class, key).build();
970 Optional<InternalTunnel> tunnelsOptional =
971 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, intIID, dataBroker);
972 if (tunnelsOptional.isPresent()) {
973 List<String> tunnelInterfaceNames = tunnelsOptional
974 .get().getTunnelInterfaceNames();
975 if (tunnelInterfaceNames != null && !tunnelInterfaceNames.isEmpty()) {
976 String tunnelInterfaceName = tunnelInterfaceNames.get(0);
977 LOG.trace("Internal Tunnel added {}", tunnelInterfaceName);
978 tunnels.add(tunnelInterfaceName);
983 if (hwVteps != null && !hwVteps.isEmpty()) {
984 for (HwVtep hwVtep : hwVteps) {
985 tunnels.add(getExtTunnel(hwVtep.getNodeId(), vtepLocal.getDpnId().toString(),
986 tunType, dataBroker));
987 tunnels.add(getExtTunnel(vtepLocal.getDpnId().toString(), hwVtep.getNodeId(),
988 tunType, dataBroker));
996 for (HwVtep hwVtep : hwVteps) {
997 for (HwVtep hwVtepOther : hwVteps) {
998 if (!hwVtep.getHwIp().equals(hwVtepOther.getHwIp())) {
999 tunnels.add(getExtTunnel(hwVtep.getNodeId(), hwVtepOther.getNodeId(),
1000 tunType, dataBroker));
1001 tunnels.add(getExtTunnel(hwVtepOther.getNodeId(), hwVtep.getNodeId(),
1002 tunType, dataBroker));
1011 public static List<String> getInternalTunnelsofTzone(String tzone, DataBroker dataBroker) {
1012 List<String> tunnels = new ArrayList<>();
1013 LOG.trace("Getting internal tunnels of {}",tzone);
1014 InstanceIdentifier<TransportZone> path = InstanceIdentifier.builder(TransportZones.class)
1015 .child(TransportZone.class, new TransportZoneKey(tzone)).build();
1016 Optional<TransportZone> transportZoneOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
1018 if (transportZoneOptional.isPresent()) {
1019 TransportZone transportZone = transportZoneOptional.get();
1020 if (transportZone.getSubnets() != null && !transportZone.getSubnets().isEmpty()) {
1021 for (Subnets sub : transportZone.getSubnets()) {
1022 if (sub.getVteps() != null && !sub.getVteps().isEmpty()) {
1023 for (Vteps vtepLocal : sub.getVteps()) {
1024 for (Vteps vtepRemote : sub.getVteps()) {
1025 if (!vtepLocal.equals(vtepRemote)) {
1026 InternalTunnelKey key =
1027 new InternalTunnelKey(vtepRemote.getDpnId(), vtepLocal.getDpnId(),
1028 transportZone.getTunnelType());
1029 InstanceIdentifier<InternalTunnel> intIID =
1030 InstanceIdentifier.builder(TunnelList.class)
1031 .child(InternalTunnel.class, key).build();
1032 Optional<InternalTunnel> tunnelsOptional =
1033 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, intIID, dataBroker);
1034 if (tunnelsOptional.isPresent()) {
1035 List<String> tunnelInterfaceNames = tunnelsOptional.get()
1036 .getTunnelInterfaceNames();
1037 if (tunnelInterfaceNames != null && !tunnelInterfaceNames.isEmpty()) {
1038 String tunnelInterfaceName = tunnelInterfaceNames.get(0);
1039 LOG.trace("Internal Tunnel added {}", tunnelInterfaceName);
1040 tunnels.add(tunnelInterfaceName);
1053 private static String getExtTunnel(String nodeId, String dpId,Class<? extends TunnelTypeBase> tunType, DataBroker
1055 LOG.trace("getting ext tunnel for {} and dpId {}",nodeId,dpId);
1056 ExternalTunnelKey key = getExternalTunnelKey(dpId, nodeId, tunType);
1057 InstanceIdentifier<ExternalTunnel> intIID = InstanceIdentifier.builder(ExternalTunnelList.class)
1058 .child(ExternalTunnel.class, key).build();
1059 Optional<ExternalTunnel> tunnelsOptional =
1060 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, intIID, dataBroker);
1061 if (tunnelsOptional.isPresent()) {
1062 String tunnelInterfaceName = tunnelsOptional.get().getTunnelInterfaceName();
1063 LOG.trace("ext tunnel returned {} ", tunnelInterfaceName);
1064 return tunnelInterfaceName;
1069 public static ExternalTunnelKey getExternalTunnelKey(String dst , String src,
1070 Class<? extends TunnelTypeBase> tunType) {
1071 if (src.indexOf("physicalswitch") > 0) {
1072 src = src.substring(0, src.indexOf("physicalswitch") - 1);
1074 if (dst.indexOf("physicalswitch") > 0) {
1075 dst = dst.substring(0, dst.indexOf("physicalswitch") - 1);
1077 return new ExternalTunnelKey(dst, src, tunType);
1080 public static List<TunnelEndPoints> getTEPsForDpn(BigInteger srcDpn, List<DPNTEPsInfo> dpnList) {
1081 for (DPNTEPsInfo dpn : dpnList) {
1082 if (dpn.getDPNID().equals(srcDpn)) {
1083 return dpn.getTunnelEndPoints() ;
1089 public static TunnelList getAllInternalTunnels(DataBroker broker) {
1090 InstanceIdentifier<TunnelList> tunnelListInstanceIdentifier =
1091 InstanceIdentifier.builder(TunnelList.class).build();
1092 return read(LogicalDatastoreType.CONFIGURATION, tunnelListInstanceIdentifier, broker).orNull();
1095 public static List<InternalTunnel> getAllInternalTunnels(DataBroker dataBroker,
1096 LogicalDatastoreType datastoreType) {
1097 List<InternalTunnel> result = null;
1098 InstanceIdentifier<TunnelList> iid = InstanceIdentifier.builder(TunnelList.class).build();
1099 Optional<TunnelList> tunnelList = read(LogicalDatastoreType.CONFIGURATION, iid, dataBroker);
1100 if (tunnelList.isPresent()) {
1101 result = tunnelList.get().getInternalTunnel();
1103 if (result == null) {
1104 result = Collections.emptyList();
1109 public static InternalTunnel getInternalTunnel(String interfaceName, DataBroker broker) {
1110 InternalTunnel internalTunnel = null;
1111 internalTunnel = itmCache.getInternalTunnel(interfaceName);
1112 if (internalTunnel == null) {
1113 updateTunnelsCache(broker);
1114 internalTunnel = itmCache.getInternalTunnel(interfaceName);
1116 return internalTunnel;
1119 public static ExternalTunnel getExternalTunnel(String interfaceName, DataBroker broker) {
1120 ExternalTunnel externalTunnel = null;
1121 externalTunnel = itmCache.getExternalTunnel(interfaceName);
1122 if (externalTunnel == null) {
1123 updateTunnelsCache(broker);
1124 externalTunnel = itmCache.getExternalTunnel(interfaceName);
1126 return externalTunnel;
1129 public static List<ExternalTunnel> getAllExternalTunnels(DataBroker broker) {
1130 List<ExternalTunnel> result = null;
1131 InstanceIdentifier<ExternalTunnelList> id = InstanceIdentifier.builder(ExternalTunnelList.class).build();
1132 Optional<ExternalTunnelList> tunnelList = read(LogicalDatastoreType.CONFIGURATION, id, broker);
1133 if (tunnelList.isPresent()) {
1134 result = tunnelList.get().getExternalTunnel();
1136 if (result == null) {
1137 result = Collections.emptyList();
1142 public static List<ExternalTunnel> getAllExternalTunnels(DataBroker dataBroker,
1143 LogicalDatastoreType datastoreType) {
1144 List<ExternalTunnel> result = null;
1145 InstanceIdentifier<ExternalTunnelList> iid = InstanceIdentifier.builder(ExternalTunnelList.class).build();
1146 Optional<ExternalTunnelList> tunnelList = read(LogicalDatastoreType.CONFIGURATION, iid, dataBroker);
1147 if (tunnelList.isPresent()) {
1148 result = tunnelList.get().getExternalTunnel();
1150 if (result == null) {
1151 result = Collections.emptyList();
1156 public static String convertTunnelTypetoString(Class<? extends TunnelTypeBase> tunType) {
1157 String tunnelType = ITMConstants.TUNNEL_TYPE_VXLAN;
1158 if (tunType.equals(TunnelTypeVxlan.class)) {
1159 tunnelType = ITMConstants.TUNNEL_TYPE_VXLAN ;
1160 } else if (tunType.equals(TunnelTypeGre.class)) {
1161 tunnelType = ITMConstants.TUNNEL_TYPE_GRE ;
1162 } else if (tunType.equals(TunnelTypeMplsOverGre.class)) {
1163 tunnelType = ITMConstants.TUNNEL_TYPE_MPLSoGRE;
1164 } else if (tunType.equals(TunnelTypeLogicalGroup.class)) {
1165 tunnelType = ITMConstants.TUNNEL_TYPE_LOGICAL_GROUP_VXLAN;
1171 public static boolean isItmIfType(Class<? extends InterfaceType> ifType) {
1172 return ifType != null && ifType.isAssignableFrom(Tunnel.class);
1175 public static StateTunnelListKey getTunnelStateKey(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
1176 .interfaces.rev140508.interfaces.state.Interface iface) {
1177 StateTunnelListKey key = null;
1178 if (isItmIfType(iface.getType())) {
1179 key = new StateTunnelListKey(iface.getName());
1184 public static void updateTunnelsCache(DataBroker broker) {
1185 List<InternalTunnel> internalTunnels = getAllInternalTunnels(broker, LogicalDatastoreType.CONFIGURATION);
1186 for (InternalTunnel tunnel : internalTunnels) {
1187 itmCache.addInternalTunnel(tunnel);
1189 List<ExternalTunnel> externalTunnels = getAllExternalTunnels(broker, LogicalDatastoreType.CONFIGURATION);
1190 for (ExternalTunnel tunnel : externalTunnels) {
1191 itmCache.addExternalTunnel(tunnel);
1195 public static Interface getInterface(
1196 String name, IInterfaceManager ifaceManager) {
1197 Interface result = itmCache.getInterface(name);
1198 if (result == null) {
1199 result = ifaceManager.getInterfaceInfoFromConfigDataStore(name);
1200 if (result != null) {
1201 itmCache.addInterface(result);
1207 public static StateTunnelList getTunnelState(DataBroker dataBroker, String ifaceName,
1208 InstanceIdentifier<StateTunnelList> stListId) {
1209 StateTunnelList tunnelState = (StateTunnelList)DataStoreCache
1210 .get(ITMConstants.TUNNEL_STATE_CACHE_NAME, ifaceName);
1211 if (tunnelState == null) {
1212 Optional<StateTunnelList> tunnelsState = ItmUtils
1213 .read(LogicalDatastoreType.OPERATIONAL, stListId, dataBroker);
1214 if (tunnelsState.isPresent()) {
1221 public static Class<? extends TunnelMonitoringTypeBase> readMonitoringProtocolFromCache(DataBroker dataBroker) {
1222 InstanceIdentifier<TunnelMonitorParams> iid = InstanceIdentifier.create(TunnelMonitorParams.class);
1223 TunnelMonitorParams tunnelMonitorParams = (TunnelMonitorParams) DataStoreCache
1224 .get(ITMConstants.ITM_MONIRORING_PARAMS_CACHE_NAME,iid,"MonitorParams",dataBroker,true);
1225 if (tunnelMonitorParams != null) {
1226 return tunnelMonitorParams.getMonitorProtocol();
1231 public static Class<? extends TunnelMonitoringTypeBase> determineMonitorProtocol(DataBroker dataBroker) {
1232 Class<? extends TunnelMonitoringTypeBase> monitoringProtocol =
1233 ItmUtils.readMonitoringProtocolFromCache(dataBroker);
1234 LOG.debug("determineMonitorProtocol: monitorProtocol from DS = {}", monitoringProtocol);
1235 if (monitoringProtocol == null) {
1236 monitoringProtocol = ITMConstants.DEFAULT_MONITOR_PROTOCOL;
1238 LOG.debug("determineMonitorProtocol: monitorProtocol = {}", monitoringProtocol);
1239 Boolean monitorState = ItmUtils.readMonitoringStateFromCache(dataBroker);
1240 if (monitorState == null) {
1241 monitorState = true;
1243 LOG.debug("determineMonitorProtocol: monitorState = {}", monitorState);
1244 InstanceIdentifier<TunnelMonitorParams> iid = InstanceIdentifier.builder(TunnelMonitorParams.class).build();
1245 TunnelMonitorParams protocolBuilder = new TunnelMonitorParamsBuilder().setEnabled(monitorState)
1246 .setMonitorProtocol(monitoringProtocol).build();
1247 ItmUtils.asyncUpdate(LogicalDatastoreType.OPERATIONAL,iid, protocolBuilder, dataBroker,
1248 ItmUtils.DEFAULT_CALLBACK);
1249 return monitoringProtocol;
1252 public static List<DcGatewayIp> getDcGatewayIpList(DataBroker broker) {
1253 InstanceIdentifier<DcGatewayIpList> dcGatewayIpListid =
1254 InstanceIdentifier.builder(DcGatewayIpList.class).build();
1255 Optional<DcGatewayIpList> dcGatewayIpListConfig =
1256 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, dcGatewayIpListid, broker);
1257 if (dcGatewayIpListConfig.isPresent()) {
1258 DcGatewayIpList containerList = dcGatewayIpListConfig.get();
1259 if (containerList != null) {
1260 return containerList.getDcGatewayIp();
1266 public static boolean falseIfNull(Boolean value) {
1267 return value == null ? false : value;
1270 public static <T> List<T> getIntersection(List<T> list1, List<T> list2) {
1271 List<T> list = new ArrayList<>();
1272 for (T iter : list1) {
1273 if (list2.contains(iter)) {
1277 LOG.debug(" getIntersection - L1 {}, L2 - {}, Intersection - {}", list1, list2, list);
1281 public static void addTransportZoneMembership(List<TzMembership> zones, String zoneName) {
1282 zones.add(new TzMembershipBuilder().setZoneName(zoneName).build());
1285 public static List<TzMembership> createTransportZoneMembership(String zoneName) {
1286 List<TzMembership> zones = new ArrayList<>();
1287 zones.add(new TzMembershipBuilder().setZoneName(zoneName).build());
1292 * Returns the transport zone from Configuration datastore.
1294 * @param tzName transport zone name
1295 * @param dataBroker data broker handle to perform operations on datastore
1296 * @return the TransportZone object in Config DS
1298 // FIXME: Better is to implement cache to avoid datastore read.
1299 public static TransportZone getTransportZoneFromConfigDS(String tzName, DataBroker dataBroker) {
1300 InstanceIdentifier<TransportZone> tzonePath = InstanceIdentifier.builder(TransportZones.class)
1301 .child(TransportZone.class, new TransportZoneKey(tzName)).build();
1302 Optional<TransportZone> transportZoneOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, tzonePath,
1304 if (transportZoneOptional.isPresent()) {
1305 return transportZoneOptional.get();
1311 * Gets the transport zone in TepsNotHosted list in the Configuration Datastore, based on transport zone name.
1313 * @param unknownTz transport zone name
1315 * @param dataBroker data broker handle to perform read operations on config datastore
1317 * @return the TepsNotHostedInTransportZone object in the TepsNotHosted list in Config DS
1319 public static TepsNotHostedInTransportZone getUnknownTransportZoneFromITMConfigDS(
1320 String unknownTz, DataBroker dataBroker) {
1321 InstanceIdentifier<TepsNotHostedInTransportZone> unknownTzPath =
1322 InstanceIdentifier.builder(TransportZones.class)
1323 .child(TepsNotHostedInTransportZone.class,
1324 new TepsNotHostedInTransportZoneKey(unknownTz)).build();
1325 Optional<TepsNotHostedInTransportZone> unknownTzOptional =
1326 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, unknownTzPath, dataBroker);
1327 if (unknownTzOptional.isPresent()) {
1328 return unknownTzOptional.get();
1334 * Gets the bridge datapath ID from Network topology Node's OvsdbBridgeAugmentation, in the Operational DS.
1336 * @param node Network Topology Node
1338 * @param bridge bridge name
1340 * @param dataBroker data broker handle to perform operations on datastore
1342 * @return the datapath ID of bridge in string form
1344 public static String getBridgeDpid(Node node, String bridge, DataBroker dataBroker) {
1345 OvsdbBridgeAugmentation ovsdbBridgeAugmentation = null;
1346 Node bridgeNode = null;
1347 String datapathId = null;
1349 NodeId ovsdbNodeId = node.getKey().getNodeId();
1351 NodeId brNodeId = new NodeId(ovsdbNodeId.getValue()
1352 + "/" + ITMConstants.BRIDGE_URI_PREFIX + "/" + bridge);
1354 InstanceIdentifier<Node> bridgeIid =
1356 .create(NetworkTopology.class)
1357 .child(Topology.class, new TopologyKey(IfmConstants.OVSDB_TOPOLOGY_ID))
1358 .child(Node.class,new NodeKey(brNodeId));
1360 Optional<Node> opBridgeNode = ItmUtils.read(LogicalDatastoreType.OPERATIONAL, bridgeIid, dataBroker);
1362 if (opBridgeNode.isPresent()) {
1363 bridgeNode = opBridgeNode.get();
1365 if (bridgeNode != null) {
1366 ovsdbBridgeAugmentation = bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class);
1369 if (ovsdbBridgeAugmentation != null && ovsdbBridgeAugmentation.getDatapathId() != null) {
1370 datapathId = ovsdbBridgeAugmentation.getDatapathId().getValue();
1376 * Gets the Network topology Node from Operational Datastore
1377 * based on Bridge Augmentation.
1379 * @param bridgeAugmentation bridge augmentation of OVSDB node
1381 * @param dataBroker data broker handle to perform operations on datastore
1383 * @return the Network Topology Node i.e. OVSDB node which is managing the specified bridge
1385 public static Node getOvsdbNode(OvsdbBridgeAugmentation bridgeAugmentation,
1386 DataBroker dataBroker) {
1387 Node ovsdbNode = null;
1388 Optional<Node> opOvsdbNode = null;
1389 if (bridgeAugmentation != null) {
1390 InstanceIdentifier<Node> ovsdbNodeIid =
1391 (InstanceIdentifier<Node>) bridgeAugmentation.getManagedBy().getValue();
1392 opOvsdbNode = ItmUtils.read(LogicalDatastoreType.OPERATIONAL, ovsdbNodeIid, dataBroker);
1394 if (opOvsdbNode.isPresent()) {
1395 ovsdbNode = opOvsdbNode.get();
1401 * Gets the bridge datapath ID in string form from
1402 * Network topology Node's OvsdbBridgeAugmentation in the Operational DS.
1404 * @param augmentedNode Ovsdb Augmented Network Topology Node
1406 * @return the datapath ID of bridge in string form
1408 public static String getStrDatapathId(OvsdbBridgeAugmentation augmentedNode) {
1409 String datapathId = null;
1410 if (augmentedNode != null && augmentedNode.getDatapathId() != null) {
1411 datapathId = augmentedNode.getDatapathId().getValue();
1417 * Returns the dummy subnet (255.255.255.255/32) as IpPrefix object.
1419 * @return the dummy subnet (255.255.255.255/32) in IpPrefix object
1421 public static IpPrefix getDummySubnet() {
1422 return DUMMY_IP_PREFIX;
1426 * Deletes the transport zone from Configuration datastore.
1428 * @param tzName transport zone name
1429 * @param dataBroker data broker handle to perform operations on datastore
1431 public static void deleteTransportZoneFromConfigDS(String tzName, DataBroker dataBroker) {
1432 // check whether transport-zone exists in config DS.
1433 TransportZone transportZoneFromConfigDS = ItmUtils.getTransportZoneFromConfigDS(tzName, dataBroker);
1434 if (transportZoneFromConfigDS != null) {
1435 // it exists, delete default-TZ now
1436 InstanceIdentifier<TransportZone> path = InstanceIdentifier.builder(TransportZones.class)
1437 .child(TransportZone.class,
1438 new TransportZoneKey(tzName)).build();
1439 LOG.debug("Removing {} transport-zone from config DS.", tzName);
1441 SingleTransactionDataBroker.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, path);
1442 } catch (TransactionCommitFailedException e) {
1443 LOG.error("deleteTransportZoneFromConfigDS failed. {} could not be deleted.", tzName, e);
1449 * Validates the tunnelType argument and returnsTunnelTypeBase class object
1450 * corresponding to tunnelType obtained in String format.
1452 * @param tunnelType type of tunnel in string form
1454 * @return tunnel-type in TunnelTypeBase object
1456 public static Class<? extends TunnelTypeBase> getTunnelType(String tunnelType) {
1457 // validate tunnelType string, in case it is NULL or empty, then
1458 // take VXLAN tunnel type by default
1459 if (tunnelType == null || tunnelType.isEmpty()) {
1460 return TUNNEL_TYPE_MAP.get(ITMConstants.TUNNEL_TYPE_VXLAN);
1461 } else if (!tunnelType.equals(ITMConstants.TUNNEL_TYPE_VXLAN)
1462 && !tunnelType.equals(ITMConstants.TUNNEL_TYPE_GRE)) {
1463 // if tunnel type is some incorrect value, then
1464 // take VXLAN tunnel type by default
1465 return TUNNEL_TYPE_MAP.get(ITMConstants.TUNNEL_TYPE_VXLAN);
1468 // return TunnelTypeBase object corresponding to tunnel-type
1469 return TUNNEL_TYPE_MAP.get(tunnelType);
1472 public static List<TzMembership> removeTransportZoneMembership(TunnelEndPoints endPts, List<TzMembership> zones) {
1473 LOG.trace(" RemoveTransportZoneMembership TEPs {}, Membership to be removed {} ", endPts, zones);
1474 List<TzMembership> existingTzList = new ArrayList<>(endPts.getTzMembership()) ;
1475 for (TzMembership membership : zones) {
1476 existingTzList.remove(new TzMembershipBuilder().setZoneName(membership.getZoneName()).build());
1478 LOG.debug("Modified Membership List {}", existingTzList);
1479 return existingTzList;
1482 public static List<TzMembership> getOriginalTzMembership(TunnelEndPoints srcTep, BigInteger dpnId,
1483 List<DPNTEPsInfo> meshedDpnList) {
1484 LOG.trace("Original Membership for source DPN {}, source TEP {}", dpnId, srcTep);
1485 for (DPNTEPsInfo dstDpn : meshedDpnList) {
1486 if (dpnId.equals(dstDpn.getDPNID())) {
1487 List<TunnelEndPoints> endPts = dstDpn.getTunnelEndPoints();
1488 for (TunnelEndPoints tep : endPts) {
1489 if (tep.getIpAddress().equals(srcTep.getIpAddress())) {
1490 LOG.debug("Original Membership size " + tep.getTzMembership().size()) ;
1491 return tep.getTzMembership();
1499 public static StateTunnelList buildStateTunnelList(StateTunnelListKey tlKey, String name, boolean state,
1500 TunnelOperStatus tunOpStatus, IInterfaceManager ifaceManager,
1501 DataBroker broker) {
1502 StateTunnelListBuilder stlBuilder = new StateTunnelListBuilder();
1503 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface =
1504 ItmUtils.getInterface(name, ifaceManager);
1505 IfTunnel ifTunnel = iface.getAugmentation(IfTunnel.class);
1506 ParentRefs parentRefs = iface.getAugmentation(ParentRefs.class);
1507 if (ifTunnel == null && parentRefs == null) {
1510 DstInfoBuilder dstInfoBuilder = new DstInfoBuilder();
1511 SrcInfoBuilder srcInfoBuilder = new SrcInfoBuilder();
1512 dstInfoBuilder.setTepIp(ifTunnel.getTunnelDestination());
1513 srcInfoBuilder.setTepIp(ifTunnel.getTunnelSource());
1514 // TODO: Add/Improve logic for device type
1515 InternalTunnel internalTunnel = ItmUtils.itmCache.getInternalTunnel(name);
1516 ExternalTunnel externalTunnel = ItmUtils.itmCache.getExternalTunnel(name);
1517 if (internalTunnel == null && externalTunnel == null) {
1518 // both not present in cache. let us update and try again.
1519 ItmUtils.updateTunnelsCache(broker);
1520 internalTunnel = ItmUtils.itmCache.getInternalTunnel(name);
1521 externalTunnel = ItmUtils.itmCache.getExternalTunnel(name);
1523 if (internalTunnel != null) {
1524 srcInfoBuilder.setTepDeviceId(internalTunnel.getSourceDPN().toString())
1525 .setTepDeviceType(TepTypeInternal.class);
1526 dstInfoBuilder.setTepDeviceId(internalTunnel.getDestinationDPN().toString())
1527 .setTepDeviceType(TepTypeInternal.class);
1528 stlBuilder.setTransportType(internalTunnel.getTransportType());
1529 } else if (externalTunnel != null) {
1530 ExternalTunnel tunnel = ItmUtils.itmCache.getExternalTunnel(name);
1531 srcInfoBuilder.setTepDeviceId(tunnel.getSourceDevice())
1532 .setTepDeviceType(getDeviceType(tunnel.getSourceDevice()));
1533 dstInfoBuilder.setTepDeviceId(tunnel.getDestinationDevice())
1534 .setTepDeviceType(getDeviceType(tunnel.getDestinationDevice()))
1535 .setTepIp(ifTunnel.getTunnelDestination());
1536 stlBuilder.setTransportType(tunnel.getTransportType());
1538 stlBuilder.setKey(tlKey).setTunnelInterfaceName(name).setOperState(tunOpStatus).setTunnelState(state)
1539 .setDstInfo(dstInfoBuilder.build()).setSrcInfo(srcInfoBuilder.build());
1540 return stlBuilder.build();
1543 public static Class<? extends TepTypeBase> getDeviceType(String device) {
1544 if (device.startsWith("hwvtep")) {
1545 return TepTypeHwvtep.class;
1546 } else if (device.contains("IpAddress")) {
1547 return TepTypeExternal.class;
1549 return TepTypeInternal.class;
1553 public static InstanceIdentifier<StateTunnelList> buildStateTunnelListId(StateTunnelListKey tlKey) {
1554 return InstanceIdentifier.builder(TunnelsState.class)
1555 .child(StateTunnelList.class, tlKey).build();
1558 public static Optional<InternalTunnel> getInternalTunnelFromDS(BigInteger srcDpn, BigInteger destDpn,
1559 Class<? extends TunnelTypeBase> type,
1560 DataBroker dataBroker) {
1561 InstanceIdentifier<InternalTunnel> pathLogicTunnel = InstanceIdentifier.create(TunnelList.class)
1562 .child(InternalTunnel.class,
1563 new InternalTunnelKey(destDpn, srcDpn, type));
1564 //TODO: need to be replaced by cached copy
1565 return ItmUtils.read(LogicalDatastoreType.CONFIGURATION, pathLogicTunnel, dataBroker);
1568 public static boolean isTunnelAggregationUsed(Class<? extends TunnelTypeBase> tunType) {
1569 return (ItmTunnelAggregationHelper.isTunnelAggregationEnabled()
1570 && (tunType.isAssignableFrom(TunnelTypeVxlan.class)
1571 || tunType.isAssignableFrom(TunnelTypeLogicalGroup.class)));
1574 public static List<TunnelOptions> buildTunnelOptions(TunnelEndPoints tep, ItmConfig itmConfig) {
1575 List<TunnelOptions> tunOptions = new ArrayList<>();
1577 String tos = tep.getOptionTunnelTos();
1579 tos = itmConfig.getDefaultTunnelTos();
1581 /* populate tos option only if its not default value of 0 */
1582 if (tos != null && !tos.equals("0")) {
1583 TunnelOptionsBuilder optionsBuilder = new TunnelOptionsBuilder();
1584 optionsBuilder.setKey(new TunnelOptionsKey("tos"));
1585 optionsBuilder.setTunnelOption("tos");
1586 optionsBuilder.setValue(tos);
1587 tunOptions.add(optionsBuilder.build());
1590 if (tep.getTunnelType() == TunnelTypeVxlan.class && itmConfig.isGpeExtensionEnabled()) {
1591 TunnelOptionsBuilder optionsBuilder = new TunnelOptionsBuilder();
1592 optionsBuilder.setKey(new TunnelOptionsKey("exts"));
1593 optionsBuilder.setTunnelOption("exts");
1594 optionsBuilder.setValue("gpe");
1595 tunOptions.add(optionsBuilder.build());
1598 return tunOptions.isEmpty() ? null : tunOptions;
1601 public static ExternalTunnel getExternalTunnelbyExternalTunnelKey(ExternalTunnelKey externalTunnelKey,
1602 InstanceIdentifier<ExternalTunnel> path,
1603 DataBroker dataBroker) {
1604 ExternalTunnel exTunnel = itmCache.getExternalTunnelKeyToExternalTunnels().get(externalTunnelKey);
1605 if (exTunnel == null) {
1606 Optional<ExternalTunnel> ext = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
1607 if (ext != null && ext.isPresent()) {
1608 exTunnel = ext.get();