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.FutureCallback;
15 import com.google.common.util.concurrent.Futures;
16 import java.math.BigInteger;
17 import java.net.InetAddress;
18 import java.util.ArrayList;
19 import java.util.Collection;
20 import java.util.Collections;
21 import java.util.List;
22 import java.util.UUID;
23 import java.util.concurrent.ExecutionException;
24 import java.util.concurrent.Future;
25 import javax.annotation.Nonnull;
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 final class ItmUtils {
156 private static final String TUNNEL = "tun";
157 private static final IpPrefix DUMMY_IP_PREFIX = new IpPrefix(ITMConstants.DUMMY_PREFIX.toCharArray());
158 private static final long DEFAULT_MONITORING_INTERVAL = 100L;
159 public static final ItmCache ITM_CACHE = new ItmCache();
161 private static final Logger LOG = LoggerFactory.getLogger(ItmUtils.class);
163 public static final ImmutableMap<String, Class<? extends TunnelTypeBase>>
165 new ImmutableMap.Builder<String, Class<? extends TunnelTypeBase>>()
166 .put(ITMConstants.TUNNEL_TYPE_GRE, TunnelTypeGre.class)
167 .put(ITMConstants.TUNNEL_TYPE_MPLSoGRE, TunnelTypeMplsOverGre.class)
168 .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(@Nonnull 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 return new BigInteger(dpnStr[0]);
242 public static String getTrunkInterfaceName(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(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);
272 public static String getLogicalTunnelGroupName(BigInteger srcDpnId, BigInteger destDpnId) {
273 String tunnelTypeStr = ITMConstants.TUNNEL_TYPE_LOGICAL_GROUP_VXLAN;
274 String groupName = String.format("%s:%s:%s", srcDpnId.toString(), destDpnId.toString(), tunnelTypeStr);
275 LOG.trace("logical tunnel group name is {}", groupName);
276 groupName = String.format("%s%s", TUNNEL, getUniqueIdString(groupName));
280 public static InetAddress getInetAddressFromIpAddress(IpAddress ip) {
281 return InetAddresses.forString(ip.getIpv4Address().getValue());
284 public static InstanceIdentifier<DPNTEPsInfo> getDpnTepInstance(BigInteger dpIdKey) {
285 return InstanceIdentifier.builder(DpnEndpoints.class).child(DPNTEPsInfo.class, new DPNTEPsInfoKey(dpIdKey))
289 public static DPNTEPsInfo createDPNTepInfo(BigInteger dpId, List<TunnelEndPoints> endpoints) {
290 return new DPNTEPsInfoBuilder().setKey(new DPNTEPsInfoKey(dpId)).setTunnelEndPoints(endpoints).build();
293 public static TunnelEndPoints createTunnelEndPoints(BigInteger dpnId, IpAddress ipAddress, String portName,
294 boolean isOfTunnel, int vlanId, IpPrefix prefix,
295 IpAddress gwAddress, List<TzMembership> zones,
296 Class<? extends TunnelTypeBase> tunnelType,
298 // when Interface Mgr provides support to take in Dpn Id
299 return new TunnelEndPointsBuilder().setKey(new TunnelEndPointsKey(ipAddress, portName,tunnelType, vlanId))
300 .setSubnetMask(prefix).setGwIpAddress(gwAddress).setTzMembership(zones)
301 .setOptionOfTunnel(isOfTunnel).setInterfaceName(ItmUtils.getInterfaceName(dpnId, portName, vlanId))
302 .setTunnelType(tunnelType)
303 .setOptionTunnelTos(tos)
307 public static DpnEndpoints createDpnEndpoints(List<DPNTEPsInfo> dpnTepInfo) {
308 return new DpnEndpointsBuilder().setDPNTEPsInfo(dpnTepInfo).build();
311 public static InstanceIdentifier<Interface> buildId(String interfaceName) {
312 return InstanceIdentifier.builder(Interfaces.class).child(Interface.class, new InterfaceKey(interfaceName))
316 public static InstanceIdentifier<IfTunnel> buildTunnelId(String ifName) {
317 return InstanceIdentifier.builder(Interfaces.class)
318 .child(Interface.class, new InterfaceKey(ifName)).augmentation(IfTunnel.class).build();
321 public static Interface buildLogicalTunnelInterface(BigInteger dpn, String ifName, String desc, boolean enabled) {
322 InterfaceBuilder builder = new InterfaceBuilder().setKey(new InterfaceKey(ifName)).setName(ifName)
323 .setDescription(desc).setEnabled(enabled).setType(Tunnel.class);
324 ParentRefs parentRefs = new ParentRefsBuilder().setDatapathNodeIdentifier(dpn).build();
325 builder.addAugmentation(ParentRefs.class, parentRefs);
327 IfTunnel tunnel = new IfTunnelBuilder()
328 .setTunnelDestination(new IpAddress(ITMConstants.DUMMY_IP_ADDRESS.toCharArray()))
329 .setTunnelSource(new IpAddress(ITMConstants.DUMMY_IP_ADDRESS.toCharArray())).setInternal(true)
330 .setMonitorEnabled(false).setTunnelInterfaceType(TunnelTypeLogicalGroup.class)
331 .setTunnelRemoteIpFlow(false).build();
332 builder.addAugmentation(IfTunnel.class, tunnel);
333 return builder.build();
336 public static Interface buildTunnelInterface(BigInteger dpn, String ifName, String desc, boolean enabled,
337 Class<? extends TunnelTypeBase> tunType, IpAddress localIp,
338 IpAddress remoteIp, IpAddress gatewayIp, Integer vlanId,
339 boolean internal, Boolean monitorEnabled,
340 Class<? extends TunnelMonitoringTypeBase> monitorProtocol,
341 Integer monitorInterval, boolean useOfTunnel,
342 List<TunnelOptions> tunOptions) {
344 return buildTunnelInterface(dpn, ifName, desc, enabled, tunType, localIp, remoteIp, gatewayIp, vlanId,
345 internal, monitorEnabled, monitorProtocol, monitorInterval, useOfTunnel, null,
349 public static Interface buildTunnelInterface(BigInteger dpn, String ifName, String desc, boolean enabled,
350 Class<? extends TunnelTypeBase> tunType, IpAddress localIp,
351 IpAddress remoteIp, IpAddress gatewayIp, Integer vlanId,
352 boolean internal, Boolean monitorEnabled,
353 Class<? extends TunnelMonitoringTypeBase> monitorProtocol,
354 Integer monitorInterval, boolean useOfTunnel, String parentIfaceName,
355 List<TunnelOptions> tunnelOptions) {
356 InterfaceBuilder builder = new InterfaceBuilder().setKey(new InterfaceKey(ifName)).setName(ifName)
357 .setDescription(desc).setEnabled(enabled).setType(Tunnel.class);
358 ParentRefs parentRefs =
359 new ParentRefsBuilder().setDatapathNodeIdentifier(dpn).setParentInterface(parentIfaceName).build();
360 builder.addAugmentation(ParentRefs.class, parentRefs);
361 Long monitoringInterval = null;
363 IfL2vlan l2vlan = new IfL2vlanBuilder().setVlanId(new VlanId(vlanId)).build();
364 builder.addAugmentation(IfL2vlan.class, l2vlan);
366 LOG.debug("buildTunnelInterface: monitorProtocol = {} and monitorInterval = {}",
367 monitorProtocol.getName(),monitorInterval);
369 if (monitorInterval != null) {
370 monitoringInterval = monitorInterval.longValue();
373 IfTunnel tunnel = new IfTunnelBuilder().setTunnelDestination(remoteIp).setTunnelGateway(gatewayIp)
374 .setTunnelSource(localIp).setTunnelInterfaceType(tunType).setInternal(internal)
375 .setMonitorEnabled(monitorEnabled).setMonitorProtocol(monitorProtocol)
376 .setMonitorInterval(monitoringInterval).setTunnelRemoteIpFlow(useOfTunnel)
377 .setTunnelOptions(tunnelOptions)
379 builder.addAugmentation(IfTunnel.class, tunnel);
380 return builder.build();
383 public static Interface buildHwTunnelInterface(String tunnelIfName, String desc, boolean enabled, String topoId,
384 String nodeId, Class<? extends TunnelTypeBase> tunType,
385 IpAddress srcIp, IpAddress destIp, IpAddress gwIp,
386 Boolean monitorEnabled,
387 Class<? extends TunnelMonitoringTypeBase> monitorProtocol,
388 Integer monitorInterval) {
389 InterfaceBuilder builder = new InterfaceBuilder().setKey(new InterfaceKey(tunnelIfName))
390 .setName(tunnelIfName).setDescription(desc).setEnabled(enabled).setType(Tunnel.class);
391 List<NodeIdentifier> nodeIds = new ArrayList<>();
392 NodeIdentifier hwNode = new NodeIdentifierBuilder().setKey(new NodeIdentifierKey(topoId))
393 .setTopologyId(topoId).setNodeId(nodeId).build();
395 ParentRefs parent = new ParentRefsBuilder().setNodeIdentifier(nodeIds).build();
396 builder.addAugmentation(ParentRefs.class, parent);
397 IfTunnel tunnel = new IfTunnelBuilder().setTunnelDestination(destIp).setTunnelGateway(gwIp)
398 .setTunnelSource(srcIp).setMonitorEnabled(monitorEnabled == null || monitorEnabled)
399 .setMonitorProtocol(monitorProtocol == null ? ITMConstants.DEFAULT_MONITOR_PROTOCOL : monitorProtocol)
400 .setMonitorInterval(DEFAULT_MONITORING_INTERVAL).setTunnelInterfaceType(tunType).setInternal(false)
402 builder.addAugmentation(IfTunnel.class, tunnel);
403 LOG.trace("iftunnel {} built from hwvtep {} ", tunnel, nodeId);
404 return builder.build();
407 public static InternalTunnel buildInternalTunnel(BigInteger srcDpnId, BigInteger dstDpnId,
408 Class<? extends TunnelTypeBase> tunType,
409 String trunkInterfaceName) {
410 return new InternalTunnelBuilder().setKey(new InternalTunnelKey(dstDpnId, srcDpnId, tunType))
411 .setDestinationDPN(dstDpnId)
412 .setSourceDPN(srcDpnId).setTransportType(tunType)
413 .setTunnelInterfaceNames(Collections.singletonList(trunkInterfaceName)).build();
416 public static ExternalTunnel buildExternalTunnel(String srcNode, String dstNode,
417 Class<? extends TunnelTypeBase> tunType,
418 String trunkInterfaceName) {
419 return new ExternalTunnelBuilder().setKey(
420 new ExternalTunnelKey(dstNode, srcNode, tunType))
421 .setSourceDevice(srcNode).setDestinationDevice(dstNode)
422 .setTunnelInterfaceName(trunkInterfaceName)
423 .setTransportType(tunType).build();
426 public static List<DPNTEPsInfo> getTunnelMeshInfo(DataBroker dataBroker) {
427 // Read the Mesh Information from Cache if not read from the DS
428 List<DPNTEPsInfo> dpnTEPs = getTunnelMeshInfo() ;
429 if (dpnTEPs != null) {
433 // Read the EndPoint Info from the operational database
434 InstanceIdentifierBuilder<DpnEndpoints> depBuilder = InstanceIdentifier.builder(DpnEndpoints.class);
435 InstanceIdentifier<DpnEndpoints> deps = depBuilder.build();
436 Optional<DpnEndpoints> dpnEps = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, deps, dataBroker);
437 if (dpnEps.isPresent()) {
438 DpnEndpoints tn = dpnEps.get();
439 dpnTEPs = tn.getDPNTEPsInfo();
440 LOG.debug("Read from CONFIGURATION datastore - No. of Dpns " , dpnTEPs.size());
442 LOG.debug("No Dpn information in CONFIGURATION datastore ");
447 // Reading the Mesh Information from Cache
448 private static List<DPNTEPsInfo> getTunnelMeshInfo() {
449 List<DPNTEPsInfo> dpnTepsInfo = null;
450 List<Object> values = DataStoreCache.getValues(ITMConstants.DPN_TEPs_Info_CACHE_NAME);
451 if (values != null) {
452 dpnTepsInfo = new ArrayList<>() ;
453 for (Object value : values) {
454 dpnTepsInfo.add((DPNTEPsInfo)value) ;
460 public static int getUniqueId(IdManagerService idManager, String idKey) {
461 AllocateIdInput getIdInput = new AllocateIdInputBuilder()
462 .setPoolName(ITMConstants.ITM_IDPOOL_NAME)
463 .setIdKey(idKey).build();
466 Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
467 RpcResult<AllocateIdOutput> rpcResult = result.get();
468 if (rpcResult.isSuccessful()) {
469 return rpcResult.getResult().getIdValue().intValue();
471 LOG.warn("RPC Call to Get Unique Id returned with Errors {}", rpcResult.getErrors());
473 } catch (InterruptedException | ExecutionException e) {
474 LOG.warn("Exception when getting Unique Id",e);
479 private static String getUniqueIdString(String idKey) {
480 return UUID.nameUUIDFromBytes(idKey.getBytes()).toString().substring(0, 12).replace("-", "");
483 public static void releaseId(IdManagerService idManager, String idKey) {
484 ReleaseIdInput idInput =
485 new ReleaseIdInputBuilder().setPoolName(ITMConstants.ITM_IDPOOL_NAME).setIdKey(idKey).build();
487 Future<RpcResult<Void>> result = idManager.releaseId(idInput);
488 RpcResult<Void> rpcResult = result.get();
489 if (!rpcResult.isSuccessful()) {
490 LOG.warn("RPC Call to Get Unique Id returned with Errors {}", rpcResult.getErrors());
492 } catch (InterruptedException | ExecutionException e) {
493 LOG.warn("Exception when getting Unique Id for key {}", idKey, e);
497 public static List<DPNTEPsInfo> getDpnTepListFromDpnId(DataBroker dataBroker, List<BigInteger> dpnIds) {
498 List<DPNTEPsInfo> meshedDpnList = getTunnelMeshInfo(dataBroker) ;
499 List<DPNTEPsInfo> cfgDpnList = new ArrayList<>();
500 if (null != meshedDpnList) {
501 for (BigInteger dpnId : dpnIds) {
502 for (DPNTEPsInfo teps : meshedDpnList) {
503 if (dpnId.equals(teps.getDPNID())) {
504 cfgDpnList.add(teps);
512 @SuppressWarnings("checkstyle:IllegalCatch")
513 public static void setUpOrRemoveTerminatingServiceTable(BigInteger dpnId, IMdsalApiManager mdsalManager,
515 String logmsg = addFlag ? "Installing" : "Removing";
516 LOG.trace("{}PUNT to Controller flow in DPN {} ", logmsg, dpnId);
517 List<ActionInfo> listActionInfo = new ArrayList<>();
518 listActionInfo.add(new ActionPuntToController());
521 List<MatchInfo> mkMatches = new ArrayList<>();
523 mkMatches.add(new MatchTunnelId(BigInteger.valueOf(ITMConstants.LLDP_SERVICE_ID)));
525 List<InstructionInfo> mkInstructions = new ArrayList<>();
526 mkInstructions.add(new InstructionApplyActions(listActionInfo));
528 FlowEntity terminatingServiceTableFlowEntity = MDSALUtil
529 .buildFlowEntity(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE,
530 getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE, ITMConstants.LLDP_SERVICE_ID),
531 5, String.format("%s:%d","ITM Flow Entry ", ITMConstants.LLDP_SERVICE_ID), 0, 0,
532 ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(ITMConstants.LLDP_SERVICE_ID)),
533 mkMatches, mkInstructions);
535 mdsalManager.installFlow(terminatingServiceTableFlowEntity);
537 mdsalManager.removeFlow(terminatingServiceTableFlowEntity);
539 } catch (Exception e) {
540 LOG.error("Error while setting up Table 36 for {}", dpnId, e);
544 private static String getFlowRef(long termSvcTable, int svcId) {
545 return String.valueOf(termSvcTable) + svcId;
548 public static InstanceIdentifier<VtepConfigSchema> getVtepConfigSchemaIdentifier(String schemaName) {
549 return InstanceIdentifier.builder(VtepConfigSchemas.class)
550 .child(VtepConfigSchema.class, new VtepConfigSchemaKey(schemaName)).build();
553 public static InstanceIdentifier<VtepConfigSchema> getVtepConfigSchemaIdentifier() {
554 return InstanceIdentifier.builder(VtepConfigSchemas.class).child(VtepConfigSchema.class).build();
557 public static InstanceIdentifier<VtepConfigSchemas> getVtepConfigSchemasIdentifier() {
558 return InstanceIdentifier.builder(VtepConfigSchemas.class).build();
561 public static InstanceIdentifier<VtepIpPool> getVtepIpPoolIdentifier(String subnetCidr) {
562 return InstanceIdentifier.builder(VtepIpPools.class).child(VtepIpPool.class, new VtepIpPoolKey(subnetCidr))
566 public static VtepConfigSchema validateForAddVtepConfigSchema(VtepConfigSchema schema,
567 List<VtepConfigSchema> existingSchemas) {
568 VtepConfigSchema validSchema = validateVtepConfigSchema(schema);
569 for (VtepConfigSchema existingSchema : emptyIfNull(existingSchemas)) {
570 if (!StringUtils.equalsIgnoreCase(schema.getSchemaName(), existingSchema.getSchemaName())
571 && schema.getSubnet().equals(existingSchema.getSubnet())) {
572 String subnetCidr = getSubnetCidrAsString(schema.getSubnet());
573 Preconditions.checkArgument(false, "VTEP schema with subnet [" + subnetCidr
574 + "] already exists. Multiple VTEP schemas with same subnet is not allowed.");
577 if (isNotEmpty(getDpnIdList(validSchema.getDpnIds()))) {
578 String tzone = validSchema.getTransportZoneName();
579 List<BigInteger> lstDpns = getConflictingDpnsAlreadyConfiguredWithTz(validSchema.getSchemaName(), tzone,
580 getDpnIdList(validSchema.getDpnIds()), existingSchemas);
581 if (!lstDpns.isEmpty()) {
582 Preconditions.checkArgument(false, "DPN's " + lstDpns + " already configured for transport zone "
583 + tzone + ". Only one end point per transport Zone per Dpn is allowed.");
585 if (schema.getTunnelType().equals(TunnelTypeGre.class)) {
586 validateForSingleGreTep(validSchema.getSchemaName(), getDpnIdList(validSchema.getDpnIds()),
593 private static void validateForSingleGreTep(String schemaName, List<BigInteger> lstDpnsForAdd,
594 List<VtepConfigSchema> existingSchemas) {
595 for (VtepConfigSchema existingSchema : emptyIfNull(existingSchemas)) {
596 if (TunnelTypeGre.class.equals(existingSchema.getTunnelType())
597 && !StringUtils.equalsIgnoreCase(schemaName, existingSchema.getSchemaName())) {
598 List<BigInteger> lstConflictingDpns = new ArrayList<>(getDpnIdList(existingSchema.getDpnIds()));
599 lstConflictingDpns.retainAll(emptyIfNull(lstDpnsForAdd));
600 if (!lstConflictingDpns.isEmpty()) {
601 String errMsg = "DPN's " + lstConflictingDpns
602 + " already configured with GRE TEP. Mutiple GRE TEP's on a single DPN are not allowed.";
603 Preconditions.checkArgument(false, errMsg);
609 public static VtepConfigSchema validateVtepConfigSchema(VtepConfigSchema schema) {
610 Preconditions.checkNotNull(schema);
611 Preconditions.checkArgument(StringUtils.isNotBlank(schema.getSchemaName()));
612 Preconditions.checkArgument(StringUtils.isNotBlank(schema.getPortName()));
613 Preconditions.checkArgument(schema.getVlanId() >= 0 && schema.getVlanId() < 4095,
614 "Invalid VLAN ID, range (0-4094)");
615 Preconditions.checkArgument(StringUtils.isNotBlank(schema.getTransportZoneName()));
616 Preconditions.checkNotNull(schema.getSubnet());
617 String subnetCidr = getSubnetCidrAsString(schema.getSubnet());
618 SubnetUtils subnetUtils = new SubnetUtils(subnetCidr);
619 IpAddress gatewayIp = schema.getGatewayIp();
620 if (gatewayIp != null) {
621 String strGatewayIp = String.valueOf(gatewayIp.getValue());
622 if (!strGatewayIp.equals(ITMConstants.DUMMY_IP_ADDRESS) && !subnetUtils.getInfo().isInRange(strGatewayIp)) {
623 Preconditions.checkArgument(false, "Gateway IP address " + strGatewayIp
624 + " is not in subnet range " + subnetCidr);
627 ItmUtils.getExcludeIpAddresses(schema.getExcludeIpFilter(), subnetUtils.getInfo());
628 return new VtepConfigSchemaBuilder(schema).setTunnelType(schema.getTunnelType()).build();
631 public static String validateTunnelType(String tunnelType) {
632 if (tunnelType == null) {
633 tunnelType = ITMConstants.TUNNEL_TYPE_VXLAN;
635 tunnelType = StringUtils.upperCase(tunnelType);
636 String error = "Invalid tunnel type. Valid values: "
637 + ITMConstants.TUNNEL_TYPE_VXLAN + " | " + ITMConstants.TUNNEL_TYPE_GRE;
638 Preconditions.checkArgument(ITMConstants.TUNNEL_TYPE_VXLAN.equals(tunnelType)
639 || ITMConstants.TUNNEL_TYPE_GRE.equals(tunnelType), error);
644 private static List<BigInteger> getConflictingDpnsAlreadyConfiguredWithTz(String schemaName, String tzone,
645 List<BigInteger> lstDpns,
646 List<VtepConfigSchema> existingSchemas) {
647 List<BigInteger> lstConflictingDpns = new ArrayList<>();
648 for (VtepConfigSchema schema : emptyIfNull(existingSchemas)) {
649 if (!StringUtils.equalsIgnoreCase(schemaName, schema.getSchemaName())
650 && StringUtils.equals(schema.getTransportZoneName(), tzone)) {
651 lstConflictingDpns = new ArrayList<>(getDpnIdList(schema.getDpnIds()));
652 lstConflictingDpns.retainAll(lstDpns);
653 if (!lstConflictingDpns.isEmpty()) {
658 return lstConflictingDpns;
661 public static VtepConfigSchema constructVtepConfigSchema(String schemaName, String portName, Integer vlanId,
662 String subnetMask, String gatewayIp, String transportZone,
663 String tunnelType, List<BigInteger> dpnIds,
664 String excludeIpFilter) {
665 IpAddress gatewayIpObj = StringUtils.isBlank(gatewayIp) ? null : new IpAddress(gatewayIp.toCharArray());
666 IpPrefix subnet = StringUtils.isBlank(subnetMask) ? null : new IpPrefix(subnetMask.toCharArray());
667 Class<? extends TunnelTypeBase> tunType ;
668 if (tunnelType.equals(ITMConstants.TUNNEL_TYPE_VXLAN)) {
669 tunType = TunnelTypeVxlan.class ;
671 tunType = TunnelTypeGre.class ;
673 VtepConfigSchemaBuilder schemaBuilder = new VtepConfigSchemaBuilder().setSchemaName(schemaName)
674 .setPortName(portName).setVlanId(vlanId).setSubnet(subnet).setGatewayIp(gatewayIpObj)
675 .setTransportZoneName(transportZone).setTunnelType(tunType).setDpnIds(getDpnIdsListFromBigInt(dpnIds))
676 .setExcludeIpFilter(excludeIpFilter);
677 return schemaBuilder.build();
680 public static List<IpAddress> getExcludeIpAddresses(String excludeIpFilter, SubnetInfo subnetInfo) {
681 final List<IpAddress> lstIpAddress = new ArrayList<>();
682 if (StringUtils.isBlank(excludeIpFilter)) {
685 final String[] arrIps = StringUtils.split(excludeIpFilter, ',');
686 for (String ip : arrIps) {
687 if (StringUtils.countMatches(ip, "-") == 1) {
688 final String[] arrIpRange = StringUtils.split(ip, '-');
689 String strStartIp = StringUtils.trim(arrIpRange[0]);
690 String strEndIp = StringUtils.trim(arrIpRange[1]);
691 Preconditions.checkArgument(InetAddresses.isInetAddress(strStartIp),
692 "Invalid exclude IP filter: invalid IP address value " + strStartIp);
693 Preconditions.checkArgument(InetAddresses.isInetAddress(strEndIp),
694 "Invalid exclude IP filter: invalid IP address value " + strEndIp);
695 Preconditions.checkArgument(subnetInfo.isInRange(strStartIp),
696 "Invalid exclude IP filter: IP address [" + strStartIp
697 + "] not in subnet range " + subnetInfo.getCidrSignature());
698 Preconditions.checkArgument(subnetInfo.isInRange(strEndIp),
699 "Invalid exclude IP filter: IP address [" + strEndIp
700 + "] not in subnet range " + subnetInfo.getCidrSignature());
701 int startIp = subnetInfo.asInteger(strStartIp);
702 int endIp = subnetInfo.asInteger(strEndIp);
704 Preconditions.checkArgument(startIp < endIp,
705 "Invalid exclude IP filter: Invalid range [" + ip + "] ");
706 for (int iter = startIp; iter <= endIp; iter++) {
707 String ipAddress = ipFormat(toIpArray(iter));
708 validateAndAddIpAddressToList(subnetInfo, lstIpAddress, ipAddress);
711 validateAndAddIpAddressToList(subnetInfo, lstIpAddress, ip);
717 private static void validateAndAddIpAddressToList(SubnetInfo subnetInfo, final List<IpAddress> lstIpAddress,
719 String ip = StringUtils.trim(ipAddress);
720 Preconditions.checkArgument(InetAddresses.isInetAddress(ip),
721 "Invalid exclude IP filter: invalid IP address value " + ip);
722 Preconditions.checkArgument(subnetInfo.isInRange(ip),
723 "Invalid exclude IP filter: IP address [" + ip + "] not in subnet range "
724 + subnetInfo.getCidrSignature());
725 lstIpAddress.add(new IpAddress(ip.toCharArray()));
728 private static int[] toIpArray(int val) {
729 int[] ret = new int[4];
730 for (int iter = 3; iter >= 0; --iter) {
731 ret[iter] |= val >>> 8 * (3 - iter) & 0xff;
736 private static String ipFormat(int[] octets) {
737 StringBuilder str = new StringBuilder();
738 for (int iter = 0; iter < octets.length; ++iter) {
739 str.append(octets[iter]);
740 if (iter != octets.length - 1) {
744 return str.toString();
747 public static VtepConfigSchema validateForUpdateVtepSchema(String schemaName, List<BigInteger> lstDpnsForAdd,
748 List<BigInteger> lstDpnsForDelete,
749 IITMProvider itmProvider) {
750 Preconditions.checkArgument(StringUtils.isNotBlank(schemaName));
751 if ((lstDpnsForAdd == null || lstDpnsForAdd.isEmpty())
752 && (lstDpnsForDelete == null || lstDpnsForDelete.isEmpty())) {
753 Preconditions.checkArgument(false,
754 "DPN ID list for add | delete is null or empty in schema " + schemaName);
756 VtepConfigSchema schema = itmProvider.getVtepConfigSchema(schemaName);
757 if (schema == null) {
758 Preconditions.checkArgument(false, "Specified VTEP Schema [" + schemaName
759 + "] doesn't exists!");
761 List<BigInteger> existingDpnIds = getDpnIdList(schema.getDpnIds());
762 if (isNotEmpty(lstDpnsForAdd)) {
763 List<BigInteger> lstAlreadyExistingDpns = new ArrayList<>(existingDpnIds);
764 lstAlreadyExistingDpns.retainAll(lstDpnsForAdd);
765 Preconditions.checkArgument(lstAlreadyExistingDpns.isEmpty(),
766 "DPN ID's " + lstAlreadyExistingDpns
767 + " already exists in VTEP schema [" + schemaName + "]");
768 if (schema.getTunnelType().equals(TunnelTypeGre.class)) {
769 validateForSingleGreTep(schema.getSchemaName(), lstDpnsForAdd, itmProvider.getAllVtepConfigSchemas());
772 if (isNotEmpty(lstDpnsForDelete)) {
773 if (existingDpnIds == null || existingDpnIds.isEmpty()) {
774 String builder = "DPN ID's " + lstDpnsForDelete
775 + " specified for delete from VTEP schema [" + schemaName
776 + "] are not configured in the schema.";
777 Preconditions.checkArgument(false, builder);
778 } else if (!existingDpnIds.containsAll(lstDpnsForDelete)) {
779 List<BigInteger> lstConflictingDpns = new ArrayList<>(lstDpnsForDelete);
780 lstConflictingDpns.removeAll(existingDpnIds);
781 String builder = "DPN ID's " + lstConflictingDpns
782 + " specified for delete from VTEP schema [" + schemaName
783 + "] are not configured in the schema.";
784 Preconditions.checkArgument(false, builder);
790 public static String getSubnetCidrAsString(IpPrefix subnet) {
791 return subnet == null ? StringUtils.EMPTY : String.valueOf(subnet.getValue());
794 public static <T> List<T> emptyIfNull(List<T> list) {
795 return list == null ? Collections.emptyList() : list;
798 public static <T> boolean isEmpty(Collection<T> collection) {
799 return collection == null || collection.isEmpty();
802 public static <T> boolean isNotEmpty(Collection<T> collection) {
803 return !isEmpty(collection);
806 public static HwVtep createHwVtepObject(String topoId, String nodeId, IpAddress ipAddress, IpPrefix ipPrefix,
807 IpAddress gatewayIP, int vlanID,
808 Class<? extends TunnelTypeBase> tunneltype, TransportZone transportZone) {
809 HwVtep hwVtep = new HwVtep();
810 hwVtep.setGatewayIP(gatewayIP);
811 hwVtep.setHwIp(ipAddress);
812 hwVtep.setIpPrefix(ipPrefix);
813 hwVtep.setNodeId(nodeId);
814 hwVtep.setTopoId(topoId);
815 hwVtep.setTransportZone(transportZone.getZoneName());
816 hwVtep.setTunnelType(tunneltype);
817 hwVtep.setVlanID(vlanID);
821 public static String getHwParentIf(String topoId, String srcNodeid) {
822 return String.format("%s:%s", topoId, srcNodeid);
825 public static <T extends DataObject> void syncWrite(LogicalDatastoreType datastoreType,
826 InstanceIdentifier<T> path, T data, DataBroker broker) {
827 WriteTransaction tx = broker.newWriteOnlyTransaction();
828 tx.put(datastoreType, path, data, true);
831 } catch (InterruptedException | ExecutionException e) {
832 LOG.error("ITMUtils:SyncWrite , Error writing to datastore (path, data) : ({}, {})", path, data);
833 throw new RuntimeException(e.getMessage(), e);
837 public static List<BigInteger> getDpnIdList(List<DpnIds> dpnIds) {
838 List<BigInteger> dpnList = new ArrayList<>() ;
839 for (DpnIds dpn : dpnIds) {
840 dpnList.add(dpn.getDPN()) ;
845 public static List<DpnIds> getDpnIdsListFromBigInt(List<BigInteger> dpnIds) {
846 List<DpnIds> dpnIdList = new ArrayList<>();
847 DpnIdsBuilder builder = new DpnIdsBuilder();
848 for (BigInteger dpnId : dpnIds) {
849 dpnIdList.add(builder.setKey(new DpnIdsKey(dpnId)).setDPN(dpnId).build());
854 public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces
855 .rev140508.interfaces.state.Interface> buildStateInterfaceId(
856 String interfaceName) {
857 return InstanceIdentifier.builder(InterfacesState.class)
858 .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
859 .state.Interface.class,
860 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces
861 .rev140508.interfaces.state.InterfaceKey(
862 interfaceName)).build();
865 public static Boolean readMonitoringStateFromCache(DataBroker dataBroker) {
866 InstanceIdentifier<TunnelMonitorParams> iid = InstanceIdentifier.create(TunnelMonitorParams.class);
867 TunnelMonitorParams tunnelMonitorParams = (TunnelMonitorParams) DataStoreCache
868 .get(ITMConstants.ITM_MONIRORING_PARAMS_CACHE_NAME,iid,"MonitorParams",dataBroker,true);
869 if (tunnelMonitorParams != null) {
870 return tunnelMonitorParams.isEnabled();
872 return ITMConstants.DEFAULT_MONITOR_ENABLED;
876 private static Integer readMonitorIntervalfromCache(DataBroker dataBroker) {
877 InstanceIdentifier<TunnelMonitorInterval> iid = InstanceIdentifier.create(TunnelMonitorInterval.class);
878 TunnelMonitorInterval tunnelMonitorIOptional = (TunnelMonitorInterval)DataStoreCache
879 .get(ITMConstants.ITM_MONIRORING_PARAMS_CACHE_NAME,iid,"Interval",dataBroker,true);
880 if (tunnelMonitorIOptional != null) {
881 return tunnelMonitorIOptional.getInterval();
886 public static Integer determineMonitorInterval(DataBroker dataBroker) {
887 Integer monitorInterval = ItmUtils.readMonitorIntervalfromCache(dataBroker);
888 LOG.debug("determineMonitorInterval: monitorInterval from DS = {}", monitorInterval);
889 if (monitorInterval == null) {
890 Class<? extends TunnelMonitoringTypeBase> monitorProtocol = determineMonitorProtocol(dataBroker);
891 if (monitorProtocol.isAssignableFrom(TunnelMonitoringTypeBfd.class)) {
892 monitorInterval = ITMConstants.BFD_DEFAULT_MONITOR_INTERVAL;
894 monitorInterval = ITMConstants.DEFAULT_MONITOR_INTERVAL;
897 LOG.debug("determineMonitorInterval: monitorInterval = {}", monitorInterval);
898 InstanceIdentifier<TunnelMonitorInterval> iid = InstanceIdentifier.builder(TunnelMonitorInterval.class).build();
899 TunnelMonitorInterval intervalBuilder = new TunnelMonitorIntervalBuilder().setInterval(monitorInterval).build();
900 ItmUtils.asyncUpdate(LogicalDatastoreType.OPERATIONAL,iid, intervalBuilder, dataBroker,
901 ItmUtils.DEFAULT_CALLBACK);
902 return monitorInterval;
905 public static List<String> getInternalTunnelInterfaces(DataBroker dataBroker) {
906 List<String> tunnelList = new ArrayList<>();
907 Collection<String> internalInterfaces = ITM_CACHE.getAllInternalInterfaces();
908 if (internalInterfaces == null) {
909 updateTunnelsCache(dataBroker);
910 internalInterfaces = ITM_CACHE.getAllInternalInterfaces();
912 LOG.debug("ItmUtils.getTunnelList Cache Internal Interfaces size: {} ", internalInterfaces.size());
913 tunnelList.addAll(internalInterfaces);
914 LOG.trace("ItmUtils.getTunnelList Internal: {}", tunnelList);
918 public static List<String> getTunnelsofTzone(List<HwVtep> hwVteps, String tzone, DataBroker dataBroker,
919 Boolean hwVtepsExist) {
920 List<String> tunnels = new ArrayList<>();
921 InstanceIdentifier<TransportZone> path = InstanceIdentifier.builder(TransportZones.class)
922 .child(TransportZone.class, new TransportZoneKey(tzone)).build();
923 Optional<TransportZone> transportZoneOptional =
924 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
925 if (transportZoneOptional.isPresent()) {
926 TransportZone transportZone = transportZoneOptional.get();
927 Class<? extends TunnelTypeBase> tunType = transportZone.getTunnelType();
928 if (transportZone.getSubnets() != null && !transportZone.getSubnets().isEmpty()) {
929 for (Subnets sub : transportZone.getSubnets()) {
930 if (sub.getVteps() != null && !sub.getVteps().isEmpty()) {
931 for (Vteps vtepLocal : sub.getVteps()) {
932 for (Vteps vtepRemote : sub.getVteps()) {
933 if (!vtepLocal.equals(vtepRemote)) {
934 InternalTunnelKey key = new InternalTunnelKey(vtepRemote.getDpnId(),
935 vtepLocal.getDpnId(), tunType);
936 InstanceIdentifier<InternalTunnel> intIID =
937 InstanceIdentifier.builder(TunnelList.class)
938 .child(InternalTunnel.class, key).build();
939 Optional<InternalTunnel> tunnelsOptional =
940 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, intIID, dataBroker);
941 if (tunnelsOptional.isPresent()) {
942 List<String> tunnelInterfaceNames = tunnelsOptional
943 .get().getTunnelInterfaceNames();
944 if (tunnelInterfaceNames != null && !tunnelInterfaceNames.isEmpty()) {
945 String tunnelInterfaceName = tunnelInterfaceNames.get(0);
946 LOG.trace("Internal Tunnel added {}", tunnelInterfaceName);
947 tunnels.add(tunnelInterfaceName);
952 if (hwVteps != null && !hwVteps.isEmpty()) {
953 for (HwVtep hwVtep : hwVteps) {
954 tunnels.add(getExtTunnel(hwVtep.getNodeId(), vtepLocal.getDpnId().toString(),
955 tunType, dataBroker));
956 tunnels.add(getExtTunnel(vtepLocal.getDpnId().toString(), hwVtep.getNodeId(),
957 tunType, dataBroker));
965 for (HwVtep hwVtep : hwVteps) {
966 for (HwVtep hwVtepOther : hwVteps) {
967 if (!hwVtep.getHwIp().equals(hwVtepOther.getHwIp())) {
968 tunnels.add(getExtTunnel(hwVtep.getNodeId(), hwVtepOther.getNodeId(),
969 tunType, dataBroker));
970 tunnels.add(getExtTunnel(hwVtepOther.getNodeId(), hwVtep.getNodeId(),
971 tunType, dataBroker));
980 public static List<String> getInternalTunnelsofTzone(String tzone, DataBroker dataBroker) {
981 List<String> tunnels = new ArrayList<>();
982 LOG.trace("Getting internal tunnels of {}",tzone);
983 InstanceIdentifier<TransportZone> path = InstanceIdentifier.builder(TransportZones.class)
984 .child(TransportZone.class, new TransportZoneKey(tzone)).build();
985 Optional<TransportZone> transportZoneOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
987 if (transportZoneOptional.isPresent()) {
988 TransportZone transportZone = transportZoneOptional.get();
989 if (transportZone.getSubnets() != null && !transportZone.getSubnets().isEmpty()) {
990 for (Subnets sub : transportZone.getSubnets()) {
991 if (sub.getVteps() != null && !sub.getVteps().isEmpty()) {
992 for (Vteps vtepLocal : sub.getVteps()) {
993 for (Vteps vtepRemote : sub.getVteps()) {
994 if (!vtepLocal.equals(vtepRemote)) {
995 InternalTunnelKey key =
996 new InternalTunnelKey(vtepRemote.getDpnId(), vtepLocal.getDpnId(),
997 transportZone.getTunnelType());
998 InstanceIdentifier<InternalTunnel> intIID =
999 InstanceIdentifier.builder(TunnelList.class)
1000 .child(InternalTunnel.class, key).build();
1001 Optional<InternalTunnel> tunnelsOptional =
1002 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, intIID, dataBroker);
1003 if (tunnelsOptional.isPresent()) {
1004 List<String> tunnelInterfaceNames = tunnelsOptional.get()
1005 .getTunnelInterfaceNames();
1006 if (tunnelInterfaceNames != null && !tunnelInterfaceNames.isEmpty()) {
1007 String tunnelInterfaceName = tunnelInterfaceNames.get(0);
1008 LOG.trace("Internal Tunnel added {}", tunnelInterfaceName);
1009 tunnels.add(tunnelInterfaceName);
1022 private static String getExtTunnel(String nodeId, String dpId,Class<? extends TunnelTypeBase> tunType, DataBroker
1024 LOG.trace("getting ext tunnel for {} and dpId {}",nodeId,dpId);
1025 ExternalTunnelKey key = getExternalTunnelKey(dpId, nodeId, tunType);
1026 InstanceIdentifier<ExternalTunnel> intIID = InstanceIdentifier.builder(ExternalTunnelList.class)
1027 .child(ExternalTunnel.class, key).build();
1028 Optional<ExternalTunnel> tunnelsOptional =
1029 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, intIID, dataBroker);
1030 if (tunnelsOptional.isPresent()) {
1031 String tunnelInterfaceName = tunnelsOptional.get().getTunnelInterfaceName();
1032 LOG.trace("ext tunnel returned {} ", tunnelInterfaceName);
1033 return tunnelInterfaceName;
1038 public static ExternalTunnelKey getExternalTunnelKey(String dst , String src,
1039 Class<? extends TunnelTypeBase> tunType) {
1040 if (src.indexOf("physicalswitch") > 0) {
1041 src = src.substring(0, src.indexOf("physicalswitch") - 1);
1043 if (dst.indexOf("physicalswitch") > 0) {
1044 dst = dst.substring(0, dst.indexOf("physicalswitch") - 1);
1046 return new ExternalTunnelKey(dst, src, tunType);
1049 public static List<TunnelEndPoints> getTEPsForDpn(BigInteger srcDpn, List<DPNTEPsInfo> dpnList) {
1050 for (DPNTEPsInfo dpn : dpnList) {
1051 if (dpn.getDPNID().equals(srcDpn)) {
1052 return dpn.getTunnelEndPoints() ;
1058 private static List<InternalTunnel> getAllInternalTunnels(DataBroker dataBroker) {
1059 List<InternalTunnel> result = null;
1060 InstanceIdentifier<TunnelList> iid = InstanceIdentifier.builder(TunnelList.class).build();
1061 Optional<TunnelList> tunnelList = read(LogicalDatastoreType.CONFIGURATION, iid, dataBroker);
1062 if (tunnelList.isPresent()) {
1063 result = tunnelList.get().getInternalTunnel();
1065 if (result == null) {
1066 result = Collections.emptyList();
1071 public static InternalTunnel getInternalTunnel(String interfaceName, DataBroker broker) {
1072 InternalTunnel internalTunnel = ITM_CACHE.getInternalTunnel(interfaceName);
1073 if (internalTunnel == null) {
1074 updateTunnelsCache(broker);
1075 internalTunnel = ITM_CACHE.getInternalTunnel(interfaceName);
1077 return internalTunnel;
1080 public static ExternalTunnel getExternalTunnel(String interfaceName, DataBroker broker) {
1081 ExternalTunnel externalTunnel = ITM_CACHE.getExternalTunnel(interfaceName);
1082 if (externalTunnel == null) {
1083 updateTunnelsCache(broker);
1084 externalTunnel = ITM_CACHE.getExternalTunnel(interfaceName);
1086 return externalTunnel;
1089 private static List<ExternalTunnel> getAllExternalTunnels(DataBroker dataBroker) {
1090 List<ExternalTunnel> result = null;
1091 InstanceIdentifier<ExternalTunnelList> iid = InstanceIdentifier.builder(ExternalTunnelList.class).build();
1092 Optional<ExternalTunnelList> tunnelList = read(LogicalDatastoreType.CONFIGURATION, iid, dataBroker);
1093 if (tunnelList.isPresent()) {
1094 result = tunnelList.get().getExternalTunnel();
1096 if (result == null) {
1097 result = Collections.emptyList();
1102 public static String convertTunnelTypetoString(Class<? extends TunnelTypeBase> tunType) {
1103 String tunnelType = ITMConstants.TUNNEL_TYPE_VXLAN;
1104 if (tunType.equals(TunnelTypeVxlan.class)) {
1105 tunnelType = ITMConstants.TUNNEL_TYPE_VXLAN ;
1106 } else if (tunType.equals(TunnelTypeGre.class)) {
1107 tunnelType = ITMConstants.TUNNEL_TYPE_GRE ;
1108 } else if (tunType.equals(TunnelTypeMplsOverGre.class)) {
1109 tunnelType = ITMConstants.TUNNEL_TYPE_MPLSoGRE;
1110 } else if (tunType.equals(TunnelTypeLogicalGroup.class)) {
1111 tunnelType = ITMConstants.TUNNEL_TYPE_LOGICAL_GROUP_VXLAN;
1117 public static boolean isItmIfType(Class<? extends InterfaceType> ifType) {
1118 return ifType != null && ifType.isAssignableFrom(Tunnel.class);
1121 public static StateTunnelListKey getTunnelStateKey(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
1122 .interfaces.rev140508.interfaces.state.Interface iface) {
1123 StateTunnelListKey key = null;
1124 if (isItmIfType(iface.getType())) {
1125 key = new StateTunnelListKey(iface.getName());
1130 private static void updateTunnelsCache(DataBroker broker) {
1131 List<InternalTunnel> internalTunnels = getAllInternalTunnels(broker);
1132 for (InternalTunnel tunnel : internalTunnels) {
1133 ITM_CACHE.addInternalTunnel(tunnel);
1135 List<ExternalTunnel> externalTunnels = getAllExternalTunnels(broker);
1136 for (ExternalTunnel tunnel : externalTunnels) {
1137 ITM_CACHE.addExternalTunnel(tunnel);
1141 public static Interface getInterface(
1142 String name, IInterfaceManager ifaceManager) {
1143 Interface result = ITM_CACHE.getInterface(name);
1144 if (result == null) {
1145 result = ifaceManager.getInterfaceInfoFromConfigDataStore(name);
1146 if (result != null) {
1147 ITM_CACHE.addInterface(result);
1153 public static StateTunnelList getTunnelState(DataBroker dataBroker, String ifaceName,
1154 InstanceIdentifier<StateTunnelList> stListId) {
1155 StateTunnelList tunnelState = (StateTunnelList)DataStoreCache
1156 .get(ITMConstants.TUNNEL_STATE_CACHE_NAME, ifaceName);
1157 if (tunnelState == null) {
1158 Optional<StateTunnelList> tunnelsState = ItmUtils
1159 .read(LogicalDatastoreType.OPERATIONAL, stListId, dataBroker);
1160 if (tunnelsState.isPresent()) {
1167 private static Class<? extends TunnelMonitoringTypeBase> readMonitoringProtocolFromCache(DataBroker dataBroker) {
1168 InstanceIdentifier<TunnelMonitorParams> iid = InstanceIdentifier.create(TunnelMonitorParams.class);
1169 TunnelMonitorParams tunnelMonitorParams = (TunnelMonitorParams) DataStoreCache
1170 .get(ITMConstants.ITM_MONIRORING_PARAMS_CACHE_NAME,iid,"MonitorParams",dataBroker,true);
1171 if (tunnelMonitorParams != null) {
1172 return tunnelMonitorParams.getMonitorProtocol();
1177 public static Class<? extends TunnelMonitoringTypeBase> determineMonitorProtocol(DataBroker dataBroker) {
1178 Class<? extends TunnelMonitoringTypeBase> monitoringProtocol =
1179 ItmUtils.readMonitoringProtocolFromCache(dataBroker);
1180 LOG.debug("determineMonitorProtocol: monitorProtocol from DS = {}", monitoringProtocol);
1181 if (monitoringProtocol == null) {
1182 monitoringProtocol = ITMConstants.DEFAULT_MONITOR_PROTOCOL;
1184 LOG.debug("determineMonitorProtocol: monitorProtocol = {}", monitoringProtocol);
1185 Boolean monitorState = ItmUtils.readMonitoringStateFromCache(dataBroker);
1186 if (monitorState == null) {
1187 monitorState = true;
1189 LOG.debug("determineMonitorProtocol: monitorState = {}", monitorState);
1190 InstanceIdentifier<TunnelMonitorParams> iid = InstanceIdentifier.builder(TunnelMonitorParams.class).build();
1191 TunnelMonitorParams protocolBuilder = new TunnelMonitorParamsBuilder().setEnabled(monitorState)
1192 .setMonitorProtocol(monitoringProtocol).build();
1193 ItmUtils.asyncUpdate(LogicalDatastoreType.OPERATIONAL,iid, protocolBuilder, dataBroker,
1194 ItmUtils.DEFAULT_CALLBACK);
1195 return monitoringProtocol;
1198 public static List<DcGatewayIp> getDcGatewayIpList(DataBroker broker) {
1199 InstanceIdentifier<DcGatewayIpList> dcGatewayIpListid =
1200 InstanceIdentifier.builder(DcGatewayIpList.class).build();
1201 Optional<DcGatewayIpList> dcGatewayIpListConfig =
1202 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, dcGatewayIpListid, broker);
1203 if (dcGatewayIpListConfig.isPresent()) {
1204 DcGatewayIpList containerList = dcGatewayIpListConfig.get();
1205 if (containerList != null) {
1206 return containerList.getDcGatewayIp();
1212 public static boolean falseIfNull(Boolean value) {
1213 return value == null ? false : value;
1216 public static <T> List<T> getIntersection(List<T> list1, List<T> list2) {
1217 List<T> list = new ArrayList<>();
1218 for (T iter : list1) {
1219 if (list2.contains(iter)) {
1223 LOG.debug(" getIntersection - L1 {}, L2 - {}, Intersection - {}", list1, list2, list);
1227 public static void addTransportZoneMembership(List<TzMembership> zones, String zoneName) {
1228 zones.add(new TzMembershipBuilder().setZoneName(zoneName).build());
1231 public static List<TzMembership> createTransportZoneMembership(String zoneName) {
1232 List<TzMembership> zones = new ArrayList<>();
1233 zones.add(new TzMembershipBuilder().setZoneName(zoneName).build());
1238 * Returns the transport zone from Configuration datastore.
1240 * @param tzName transport zone name
1241 * @param dataBroker data broker handle to perform operations on datastore
1242 * @return the TransportZone object in Config DS
1244 // FIXME: Better is to implement cache to avoid datastore read.
1245 public static TransportZone getTransportZoneFromConfigDS(String tzName, DataBroker dataBroker) {
1246 InstanceIdentifier<TransportZone> tzonePath = InstanceIdentifier.builder(TransportZones.class)
1247 .child(TransportZone.class, new TransportZoneKey(tzName)).build();
1248 Optional<TransportZone> transportZoneOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, tzonePath,
1250 if (transportZoneOptional.isPresent()) {
1251 return transportZoneOptional.get();
1257 * Gets the transport zone in TepsNotHosted list in the Configuration Datastore, based on transport zone name.
1259 * @param unknownTz transport zone name
1261 * @param dataBroker data broker handle to perform read operations on config datastore
1263 * @return the TepsNotHostedInTransportZone object in the TepsNotHosted list in Config DS
1265 public static TepsNotHostedInTransportZone getUnknownTransportZoneFromITMConfigDS(
1266 String unknownTz, DataBroker dataBroker) {
1267 InstanceIdentifier<TepsNotHostedInTransportZone> unknownTzPath =
1268 InstanceIdentifier.builder(TransportZones.class)
1269 .child(TepsNotHostedInTransportZone.class,
1270 new TepsNotHostedInTransportZoneKey(unknownTz)).build();
1271 Optional<TepsNotHostedInTransportZone> unknownTzOptional =
1272 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, unknownTzPath, dataBroker);
1273 if (unknownTzOptional.isPresent()) {
1274 return unknownTzOptional.get();
1280 * Gets the bridge datapath ID from Network topology Node's OvsdbBridgeAugmentation, in the Operational DS.
1282 * @param node Network Topology Node
1284 * @param bridge bridge name
1286 * @param dataBroker data broker handle to perform operations on datastore
1288 * @return the datapath ID of bridge in string form
1290 public static String getBridgeDpid(Node node, String bridge, DataBroker dataBroker) {
1291 OvsdbBridgeAugmentation ovsdbBridgeAugmentation = null;
1292 Node bridgeNode = null;
1293 String datapathId = null;
1295 NodeId ovsdbNodeId = node.getKey().getNodeId();
1297 NodeId brNodeId = new NodeId(ovsdbNodeId.getValue()
1298 + "/" + ITMConstants.BRIDGE_URI_PREFIX + "/" + bridge);
1300 InstanceIdentifier<Node> bridgeIid =
1302 .create(NetworkTopology.class)
1303 .child(Topology.class, new TopologyKey(IfmConstants.OVSDB_TOPOLOGY_ID))
1304 .child(Node.class,new NodeKey(brNodeId));
1306 Optional<Node> opBridgeNode = ItmUtils.read(LogicalDatastoreType.OPERATIONAL, bridgeIid, dataBroker);
1308 if (opBridgeNode.isPresent()) {
1309 bridgeNode = opBridgeNode.get();
1311 if (bridgeNode != null) {
1312 ovsdbBridgeAugmentation = bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class);
1315 if (ovsdbBridgeAugmentation != null && ovsdbBridgeAugmentation.getDatapathId() != null) {
1316 datapathId = ovsdbBridgeAugmentation.getDatapathId().getValue();
1322 * Gets the Network topology Node from Operational Datastore
1323 * based on Bridge Augmentation.
1325 * @param bridgeAugmentation bridge augmentation of OVSDB node
1327 * @param dataBroker data broker handle to perform operations on datastore
1329 * @return the Network Topology Node i.e. OVSDB node which is managing the specified bridge
1331 public static Node getOvsdbNode(OvsdbBridgeAugmentation bridgeAugmentation,
1332 DataBroker dataBroker) {
1333 Node ovsdbNode = null;
1334 Optional<Node> opOvsdbNode = Optional.absent();
1335 if (bridgeAugmentation != null) {
1336 InstanceIdentifier<Node> ovsdbNodeIid =
1337 (InstanceIdentifier<Node>) bridgeAugmentation.getManagedBy().getValue();
1338 opOvsdbNode = ItmUtils.read(LogicalDatastoreType.OPERATIONAL, ovsdbNodeIid, dataBroker);
1340 if (opOvsdbNode.isPresent()) {
1341 ovsdbNode = opOvsdbNode.get();
1347 * Gets the bridge datapath ID in string form from
1348 * Network topology Node's OvsdbBridgeAugmentation in the Operational DS.
1350 * @param augmentedNode Ovsdb Augmented Network Topology Node
1352 * @return the datapath ID of bridge in string form
1354 public static String getStrDatapathId(OvsdbBridgeAugmentation augmentedNode) {
1355 String datapathId = null;
1356 if (augmentedNode != null && augmentedNode.getDatapathId() != null) {
1357 datapathId = augmentedNode.getDatapathId().getValue();
1363 * Returns the dummy subnet (255.255.255.255/32) as IpPrefix object.
1365 * @return the dummy subnet (255.255.255.255/32) in IpPrefix object
1367 public static IpPrefix getDummySubnet() {
1368 return DUMMY_IP_PREFIX;
1372 * Deletes the transport zone from Configuration datastore.
1374 * @param tzName transport zone name
1375 * @param dataBroker data broker handle to perform operations on datastore
1377 public static void deleteTransportZoneFromConfigDS(String tzName, DataBroker dataBroker) {
1378 // check whether transport-zone exists in config DS.
1379 TransportZone transportZoneFromConfigDS = ItmUtils.getTransportZoneFromConfigDS(tzName, dataBroker);
1380 if (transportZoneFromConfigDS != null) {
1381 // it exists, delete default-TZ now
1382 InstanceIdentifier<TransportZone> path = InstanceIdentifier.builder(TransportZones.class)
1383 .child(TransportZone.class,
1384 new TransportZoneKey(tzName)).build();
1385 LOG.debug("Removing {} transport-zone from config DS.", tzName);
1387 SingleTransactionDataBroker.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, path);
1388 } catch (TransactionCommitFailedException e) {
1389 LOG.error("deleteTransportZoneFromConfigDS failed. {} could not be deleted.", tzName, e);
1395 * Validates the tunnelType argument and returnsTunnelTypeBase class object
1396 * corresponding to tunnelType obtained in String format.
1398 * @param tunnelType type of tunnel in string form
1400 * @return tunnel-type in TunnelTypeBase object
1402 public static Class<? extends TunnelTypeBase> getTunnelType(String tunnelType) {
1403 // validate tunnelType string, in case it is NULL or empty, then
1404 // take VXLAN tunnel type by default
1405 if (tunnelType == null || tunnelType.isEmpty()) {
1406 return TUNNEL_TYPE_MAP.get(ITMConstants.TUNNEL_TYPE_VXLAN);
1407 } else if (!tunnelType.equals(ITMConstants.TUNNEL_TYPE_VXLAN)
1408 && !tunnelType.equals(ITMConstants.TUNNEL_TYPE_GRE)) {
1409 // if tunnel type is some incorrect value, then
1410 // take VXLAN tunnel type by default
1411 return TUNNEL_TYPE_MAP.get(ITMConstants.TUNNEL_TYPE_VXLAN);
1414 // return TunnelTypeBase object corresponding to tunnel-type
1415 return TUNNEL_TYPE_MAP.get(tunnelType);
1418 public static List<TzMembership> removeTransportZoneMembership(TunnelEndPoints endPts, List<TzMembership> zones) {
1419 LOG.trace(" RemoveTransportZoneMembership TEPs {}, Membership to be removed {} ", endPts, zones);
1420 List<TzMembership> existingTzList = new ArrayList<>(endPts.getTzMembership()) ;
1421 for (TzMembership membership : zones) {
1422 existingTzList.remove(new TzMembershipBuilder().setZoneName(membership.getZoneName()).build());
1424 LOG.debug("Modified Membership List {}", existingTzList);
1425 return existingTzList;
1428 public static List<TzMembership> getOriginalTzMembership(TunnelEndPoints srcTep, BigInteger dpnId,
1429 List<DPNTEPsInfo> meshedDpnList) {
1430 LOG.trace("Original Membership for source DPN {}, source TEP {}", dpnId, srcTep);
1431 for (DPNTEPsInfo dstDpn : meshedDpnList) {
1432 if (dpnId.equals(dstDpn.getDPNID())) {
1433 List<TunnelEndPoints> endPts = dstDpn.getTunnelEndPoints();
1434 for (TunnelEndPoints tep : endPts) {
1435 if (tep.getIpAddress().equals(srcTep.getIpAddress())) {
1436 LOG.debug("Original Membership size " + tep.getTzMembership().size()) ;
1437 return tep.getTzMembership();
1445 public static StateTunnelList buildStateTunnelList(StateTunnelListKey tlKey, String name, boolean state,
1446 TunnelOperStatus tunOpStatus, IInterfaceManager ifaceManager,
1447 DataBroker broker) {
1448 StateTunnelListBuilder stlBuilder = new StateTunnelListBuilder();
1449 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface =
1450 ItmUtils.getInterface(name, ifaceManager);
1451 IfTunnel ifTunnel = iface.getAugmentation(IfTunnel.class);
1452 ParentRefs parentRefs = iface.getAugmentation(ParentRefs.class);
1453 if (ifTunnel == null && parentRefs == null) {
1456 DstInfoBuilder dstInfoBuilder = new DstInfoBuilder();
1457 SrcInfoBuilder srcInfoBuilder = new SrcInfoBuilder();
1458 dstInfoBuilder.setTepIp(ifTunnel.getTunnelDestination());
1459 srcInfoBuilder.setTepIp(ifTunnel.getTunnelSource());
1460 // TODO: Add/Improve logic for device type
1461 InternalTunnel internalTunnel = ItmUtils.ITM_CACHE.getInternalTunnel(name);
1462 ExternalTunnel externalTunnel = ItmUtils.ITM_CACHE.getExternalTunnel(name);
1463 if (internalTunnel == null && externalTunnel == null) {
1464 // both not present in cache. let us update and try again.
1465 ItmUtils.updateTunnelsCache(broker);
1466 internalTunnel = ItmUtils.ITM_CACHE.getInternalTunnel(name);
1467 externalTunnel = ItmUtils.ITM_CACHE.getExternalTunnel(name);
1469 if (internalTunnel != null) {
1470 srcInfoBuilder.setTepDeviceId(internalTunnel.getSourceDPN().toString())
1471 .setTepDeviceType(TepTypeInternal.class);
1472 dstInfoBuilder.setTepDeviceId(internalTunnel.getDestinationDPN().toString())
1473 .setTepDeviceType(TepTypeInternal.class);
1474 stlBuilder.setTransportType(internalTunnel.getTransportType());
1475 } else if (externalTunnel != null) {
1476 ExternalTunnel tunnel = ItmUtils.ITM_CACHE.getExternalTunnel(name);
1477 srcInfoBuilder.setTepDeviceId(tunnel.getSourceDevice())
1478 .setTepDeviceType(getDeviceType(tunnel.getSourceDevice()));
1479 dstInfoBuilder.setTepDeviceId(tunnel.getDestinationDevice())
1480 .setTepDeviceType(getDeviceType(tunnel.getDestinationDevice()))
1481 .setTepIp(ifTunnel.getTunnelDestination());
1482 stlBuilder.setTransportType(tunnel.getTransportType());
1484 stlBuilder.setKey(tlKey).setTunnelInterfaceName(name).setOperState(tunOpStatus).setTunnelState(state)
1485 .setDstInfo(dstInfoBuilder.build()).setSrcInfo(srcInfoBuilder.build());
1486 return stlBuilder.build();
1489 private static Class<? extends TepTypeBase> getDeviceType(String device) {
1490 if (device.startsWith("hwvtep")) {
1491 return TepTypeHwvtep.class;
1492 } else if (device.contains("IpAddress")) {
1493 return TepTypeExternal.class;
1495 return TepTypeInternal.class;
1499 public static InstanceIdentifier<StateTunnelList> buildStateTunnelListId(StateTunnelListKey tlKey) {
1500 return InstanceIdentifier.builder(TunnelsState.class)
1501 .child(StateTunnelList.class, tlKey).build();
1505 public static Optional<InternalTunnel> getInternalTunnelFromDS(BigInteger srcDpn, BigInteger destDpn,
1506 Class<? extends TunnelTypeBase> type,
1507 DataBroker dataBroker) {
1508 InstanceIdentifier<InternalTunnel> pathLogicTunnel = InstanceIdentifier.create(TunnelList.class)
1509 .child(InternalTunnel.class,
1510 new InternalTunnelKey(destDpn, srcDpn, type));
1511 //TODO: need to be replaced by cached copy
1512 return ItmUtils.read(LogicalDatastoreType.CONFIGURATION, pathLogicTunnel, dataBroker);
1515 public static boolean isTunnelAggregationUsed(Class<? extends TunnelTypeBase> tunType) {
1516 return (ItmTunnelAggregationHelper.isTunnelAggregationEnabled()
1517 && (tunType.isAssignableFrom(TunnelTypeVxlan.class)
1518 || tunType.isAssignableFrom(TunnelTypeLogicalGroup.class)));
1521 public static List<TunnelOptions> buildTunnelOptions(TunnelEndPoints tep, ItmConfig itmConfig) {
1522 List<TunnelOptions> tunOptions = new ArrayList<>();
1524 String tos = tep.getOptionTunnelTos();
1526 tos = itmConfig.getDefaultTunnelTos();
1528 /* populate tos option only if its not default value of 0 */
1529 if (tos != null && !tos.equals("0")) {
1530 TunnelOptionsBuilder optionsBuilder = new TunnelOptionsBuilder();
1531 optionsBuilder.setKey(new TunnelOptionsKey("tos"));
1532 optionsBuilder.setTunnelOption("tos");
1533 optionsBuilder.setValue(tos);
1534 tunOptions.add(optionsBuilder.build());
1537 if (tep.getTunnelType() == TunnelTypeVxlan.class && itmConfig.isGpeExtensionEnabled()) {
1538 TunnelOptionsBuilder optionsBuilder = new TunnelOptionsBuilder();
1539 optionsBuilder.setKey(new TunnelOptionsKey("exts"));
1540 optionsBuilder.setTunnelOption("exts");
1541 optionsBuilder.setValue("gpe");
1542 tunOptions.add(optionsBuilder.build());
1545 return tunOptions.isEmpty() ? null : tunOptions;
1548 public static ExternalTunnel getExternalTunnelbyExternalTunnelKey(ExternalTunnelKey externalTunnelKey,
1549 InstanceIdentifier<ExternalTunnel> path,
1550 DataBroker dataBroker) {
1551 ExternalTunnel exTunnel = ITM_CACHE.getExternalTunnelKeyToExternalTunnels().get(externalTunnelKey);
1552 if (exTunnel == null) {
1553 Optional<ExternalTunnel> ext = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
1554 if (ext.isPresent()) {
1555 exTunnel = ext.get();