2 * Copyright (c) 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.cli;
10 import com.google.common.base.Optional;
11 import com.google.common.base.Preconditions;
12 import java.math.BigInteger;
13 import java.util.ArrayList;
14 import java.util.HashMap;
15 import java.util.List;
17 import javax.annotation.PostConstruct;
18 import javax.annotation.PreDestroy;
19 import javax.inject.Inject;
20 import javax.inject.Singleton;
21 import org.apache.commons.lang3.StringUtils;
22 import org.apache.commons.net.util.SubnetUtils;
23 import org.apache.felix.service.command.CommandSession;
24 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
25 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
26 import org.opendaylight.genius.itm.globals.ITMConstants;
27 import org.opendaylight.genius.itm.impl.ItmUtils;
28 import org.opendaylight.genius.mdsalutil.MDSALDataStoreUtils;
29 import org.opendaylight.genius.utils.cache.DataStoreCache;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelMonitoringTypeBase;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelMonitoringTypeBfd;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelMonitoringTypeLldp;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeGre;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeMplsOverGre;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.ItmConfig;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.TunnelMonitorInterval;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.TunnelMonitorIntervalBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.TunnelMonitorParams;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.TunnelMonitorParamsBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeInternal;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelOperStatus;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelList;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZones;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZonesBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZone;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZoneBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZoneKey;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.Subnets;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.SubnetsBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.SubnetsKey;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.Vteps;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.VtepsBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.VtepsKey;
58 import org.opendaylight.yangtools.yang.binding.DataObject;
59 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
60 import org.slf4j.Logger;
61 import org.slf4j.LoggerFactory;
64 public class TepCommandHelper {
66 private static final Logger LOG = LoggerFactory.getLogger(TepCommandHelper.class);
67 private final DataBroker dataBroker;
68 private final ItmConfig itmConfig;
70 static short flag = 0;
72 * boolean flag add_or_delete --- can be set to true if the last called tep
73 * command is Tep-add else set to false when Tep-delete is called
74 * tepCommandHelper object is created only once in session initiated
76 final Map<String, Map<SubnetObject, List<Vteps>>> transportZonesHashMap = new HashMap<>();
77 private List<Subnets> subnetList = new ArrayList<>();
78 private List<TransportZone> transportZoneArrayList = new ArrayList<>();
79 private final List<Vteps> vtepDelCommitList = new ArrayList<>();
81 // private List<InstanceIdentifier<? extends DataObject>> vtepPaths = new
85 public TepCommandHelper(final DataBroker dataBroker, final ItmConfig itmConfig) {
86 this.dataBroker = dataBroker;
87 this.itmConfig = itmConfig;
91 public void start() throws Exception {
92 boolean defTzEnabled = itmConfig.isDefTzEnabled();
94 String tunnelType = itmConfig.getDefTzTunnelType();
95 if (tunnelType == null || tunnelType.isEmpty()) {
96 tunnelType = ITMConstants.TUNNEL_TYPE_VXLAN;
98 configureTunnelType(ITMConstants.DEFAULT_TRANSPORT_ZONE, tunnelType);
99 LOG.debug("{} is created with {} tunnel-type.", ITMConstants.DEFAULT_TRANSPORT_ZONE, tunnelType);
101 LOG.debug("Removing {} on start-up, def-tz-enabled is false.", ITMConstants.DEFAULT_TRANSPORT_ZONE);
102 // check if default-TZ already exists, then delete it because flag is OFF now.
103 ItmUtils.deleteTransportZoneFromConfigDS(ITMConstants.DEFAULT_TRANSPORT_ZONE, dataBroker);
105 LOG.info("TepCommandHelper Started");
109 public void close() {
110 LOG.info("TepCommandHelper Closed");
113 @SuppressWarnings("checkstyle:IllegalCatch")
114 public void createLocalCache(BigInteger dpnId, String portName, Integer vlanId, String ipAddress,
115 String subnetMask, String gatewayIp, String transportZone,
116 CommandSession session) throws TepException {
119 IpAddress ipAddressObj = null;
120 IpAddress gatewayIpObj = null;
121 IpPrefix subnetMaskObj = null;
122 final VtepsKey vtepkey = new VtepsKey(dpnId, portName);
124 ipAddressObj = new IpAddress(ipAddress.toCharArray());
125 gatewayIpObj = new IpAddress("0.0.0.0".toCharArray());
126 if (gatewayIp != null) {
127 gatewayIpObj = new IpAddress(gatewayIp.toCharArray());
129 LOG.debug("gateway is null");
131 } catch (Exception e) {
132 handleError("Invalid IpAddress. Expected: 1.0.0.0 to 254.255.255.255", session);
136 subnetMaskObj = new IpPrefix(subnetMask.toCharArray());
137 } catch (Exception e) {
138 handleError("Invalid Subnet Mask. Expected: 0.0.0.0/0 to 255.255.255.255/32", session);
142 if (!validateIPs(ipAddress, subnetMask, gatewayIp)) {
143 handleError("IpAddress and gateWayIp should belong to the subnet provided", session);
147 if (checkTepPerTzPerDpn(transportZone, dpnId)) {
148 if (session != null) {
149 session.getConsole().println("Only one end point per transport Zone per Dpn is allowed");
153 Vteps vtepCli = new VtepsBuilder().setDpnId(dpnId).setIpAddress(ipAddressObj).setKey(vtepkey)
154 .setPortname(portName).build();
155 validateForDuplicates(vtepCli, transportZone);
157 SubnetsKey subnetsKey = new SubnetsKey(subnetMaskObj);
158 SubnetObject subObCli = new SubnetObject(gatewayIpObj, subnetsKey, subnetMaskObj, vlanId);
159 if (transportZonesHashMap.containsKey(transportZone)) {
160 Map<SubnetObject, List<Vteps>> subVtepMapTemp = transportZonesHashMap.get(transportZone);
161 if (subVtepMapTemp.containsKey(subObCli)) { // if Subnet exists
162 List<Vteps> vtepListTemp = subVtepMapTemp.get(subObCli);
163 if (vtepListTemp.contains(vtepCli)) {
166 vtepListTemp.add(vtepCli);
168 } else { // subnet doesnt exist
169 if (checkExistingSubnet(subVtepMapTemp, subObCli)) {
170 if (session != null) {
171 session.getConsole().println("subnet with subnet mask "
172 + subObCli.get_key() + "already exists");
176 List<Vteps> vtepListTemp = new ArrayList<>();
177 vtepListTemp.add(vtepCli);
178 subVtepMapTemp.put(subObCli, vtepListTemp);
181 List<Vteps> vtepListTemp = new ArrayList<>();
182 vtepListTemp.add(vtepCli);
183 Map<SubnetObject, List<Vteps>> subVtepMapTemp = new HashMap<>();
184 subVtepMapTemp.put(subObCli, vtepListTemp);
185 transportZonesHashMap.put(transportZone, subVtepMapTemp);
189 private boolean validateIPs(String ipAddress, String subnetMask, String gatewayIp) {
190 SubnetUtils utils = new SubnetUtils(subnetMask);
191 if (utils.getInfo().isInRange(ipAddress) && (gatewayIp == null || utils.getInfo().isInRange(gatewayIp))) {
194 LOG.trace("InValid IP");
200 * Validate for duplicates.
204 * @param transportZone
207 public void validateForDuplicates(Vteps inputVtep, String transportZone) {
208 Map<String, TransportZone> allTransportZonesAsMap = getAllTransportZonesAsMap();
210 boolean isConfiguredTepGreType = isGreTunnelType(transportZone, allTransportZonesAsMap);
211 // Checking for duplicates in local cache
212 for (String tz : transportZonesHashMap.keySet()) {
213 boolean isGreType = isGreTunnelType(tz, allTransportZonesAsMap);
214 Map<SubnetObject, List<Vteps>> subVtepMapTemp = transportZonesHashMap.get(tz);
215 for (SubnetObject subOb : subVtepMapTemp.keySet()) {
216 List<Vteps> vtepList = subVtepMapTemp.get(subOb);
217 validateForDuplicateAndSingleGreTep(inputVtep, isConfiguredTepGreType, isGreType, vtepList);
220 // Checking for duplicates in config DS
221 for (TransportZone tz : allTransportZonesAsMap.values()) {
222 boolean isGreType = false;
223 if (tz.getTunnelType().equals(TunnelTypeGre.class)) {
226 for (Subnets sub : ItmUtils.emptyIfNull(tz.getSubnets())) {
227 List<Vteps> vtepList = sub.getVteps();
228 validateForDuplicateAndSingleGreTep(inputVtep, isConfiguredTepGreType, isGreType, vtepList);
233 private void validateForDuplicateAndSingleGreTep(Vteps inputVtep, boolean isConfiguredTepGreType, boolean isGreType,
234 List<Vteps> vtepList) {
235 if (ItmUtils.isEmpty(vtepList)) {
238 if (vtepList.contains(inputVtep)) {
239 Preconditions.checkArgument(false, "VTEP already exists");
241 BigInteger dpnId = inputVtep.getDpnId();
242 if (isConfiguredTepGreType && isGreType) {
243 for (Vteps vtep : vtepList) {
244 if (vtep.getDpnId().equals(dpnId)) {
245 String errMsg = "DPN [" + dpnId + "] already configured with GRE TEP."
246 + " Mutiple GRE TEP's on a single DPN are not allowed.";
247 Preconditions.checkArgument(false, errMsg);
254 * Gets all transport zones as map.
256 * @return all transport zones as map
258 private Map<String, TransportZone> getAllTransportZonesAsMap() {
259 TransportZones allTransportZones = getAllTransportZones();
260 Map<String, TransportZone> transportZoneMap = new HashMap<>();
261 if (null != allTransportZones) {
262 for (TransportZone tzone : ItmUtils.emptyIfNull(allTransportZones.getTransportZone())) {
263 transportZoneMap.put(tzone.getZoneName(), tzone);
266 return transportZoneMap;
270 * Checks if is gre tunnel type.
272 * @param transportZoneName
274 * @param trsnsportZoneMap
276 * @return true, if is gre tunnel type
278 private boolean isGreTunnelType(String transportZoneName, Map<String, TransportZone> trsnsportZoneMap) {
279 TransportZone tzone = trsnsportZoneMap.get(transportZoneName);
281 * if (tzone != null &&
282 * StringUtils.equalsIgnoreCase(ITMConstants.TUNNEL_TYPE_GRE,
283 * tzone.getTunnelType())) { return true; }
285 return tzone != null && tzone.getTunnelType().equals(TunnelTypeGre.class);
289 * Gets the transport zone.
291 * @param transportZoneName
293 * @return the transport zone
295 public TransportZone getTransportZone(String transportZoneName) {
296 InstanceIdentifier<TransportZone> tzonePath = InstanceIdentifier.builder(TransportZones.class)
297 .child(TransportZone.class, new TransportZoneKey(transportZoneName)).build();
298 return ItmUtils.read(LogicalDatastoreType.CONFIGURATION, tzonePath, dataBroker).orNull();
302 * Gets all transport zones.
304 * @return all transport zones
306 public TransportZones getAllTransportZones() {
307 InstanceIdentifier<TransportZones> path = InstanceIdentifier.builder(TransportZones.class).build();
308 return ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker).orNull();
311 public boolean checkExistingSubnet(Map<SubnetObject, List<Vteps>> subVtepMapTemp, SubnetObject subObCli) {
312 for (SubnetObject subOb : subVtepMapTemp.keySet()) {
313 if (subOb.get_key().equals(subObCli.get_key())) {
314 if (!subOb.get_vlanId().equals(subObCli.get_vlanId())) {
317 if (!subOb.get_gatewayIp().equals(subObCli.get_gatewayIp())) {
325 public boolean checkTepPerTzPerDpn(String tzone, BigInteger dpnId) {
326 // check in local cache
327 if (transportZonesHashMap.containsKey(tzone)) {
328 Map<SubnetObject, List<Vteps>> subVtepMapTemp = transportZonesHashMap.get(tzone);
329 for (SubnetObject subOb : subVtepMapTemp.keySet()) {
330 List<Vteps> vtepList = subVtepMapTemp.get(subOb);
331 for (Vteps vtep : vtepList) {
332 if (vtep.getDpnId().equals(dpnId)) {
340 InstanceIdentifier<TransportZone> tzonePath =
341 InstanceIdentifier.builder(TransportZones.class)
342 .child(TransportZone.class, new TransportZoneKey(tzone)).build();
343 Optional<TransportZone> transportZoneOptional =
344 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, tzonePath, dataBroker);
345 if (transportZoneOptional.isPresent()) {
346 TransportZone tz = transportZoneOptional.get();
347 if (tz.getSubnets() == null || tz.getSubnets().isEmpty()) {
350 for (Subnets sub : tz.getSubnets()) {
351 if (sub.getVteps() == null || sub.getVteps().isEmpty()) {
354 for (Vteps vtep : sub.getVteps()) {
355 if (vtep.getDpnId().equals(dpnId)) {
364 @SuppressWarnings("checkstyle:IllegalCatch")
365 public void buildTeps() {
366 TransportZones transportZonesBuilt = null;
367 TransportZone transportZone = null;
369 LOG.debug("no of teps added" + check);
370 if (transportZonesHashMap != null || !transportZonesHashMap.isEmpty()) {
371 transportZoneArrayList = new ArrayList<>();
372 for (String tz : transportZonesHashMap.keySet()) {
373 LOG.debug("transportZonesHashMap" + tz);
374 subnetList = new ArrayList<>();
375 Map<SubnetObject, List<Vteps>> subVtepMapTemp = transportZonesHashMap.get(tz);
376 for (SubnetObject subOb : subVtepMapTemp.keySet()) {
377 LOG.debug("subnets" + subOb.get_prefix());
378 List<Vteps> vtepList = subVtepMapTemp.get(subOb);
379 Subnets subnet = new SubnetsBuilder().setGatewayIp(subOb.get_gatewayIp())
380 .setKey(subOb.get_key()).setPrefix(subOb.get_prefix()).setVlanId(subOb.get_vlanId())
381 .setVteps(vtepList).build();
382 subnetList.add(subnet);
383 LOG.debug("vteps" + vtepList);
385 InstanceIdentifier<TransportZone> transportZonePath =
386 InstanceIdentifier.builder(TransportZones.class)
387 .child(TransportZone.class, new TransportZoneKey(tz)).build();
388 Optional<TransportZone> transportZoneOptional =
389 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, transportZonePath, dataBroker);
390 LOG.debug("read container from DS");
391 if (transportZoneOptional.isPresent()) {
392 TransportZone tzoneFromDs = transportZoneOptional.get();
393 LOG.debug("read tzone container" + tzoneFromDs.toString());
394 if (tzoneFromDs.getTunnelType() == null
395 || tzoneFromDs.getTunnelType().equals(TunnelTypeVxlan.class)) {
397 new TransportZoneBuilder().setKey(new TransportZoneKey(tz))
398 .setTunnelType(TunnelTypeVxlan.class).setSubnets(subnetList)
399 .setZoneName(tz).build();
400 } else if (tzoneFromDs.getTunnelType().equals(TunnelTypeGre.class)) {
402 new TransportZoneBuilder().setKey(new TransportZoneKey(tz))
403 .setTunnelType(TunnelTypeGre.class).setSubnets(subnetList)
404 .setZoneName(tz).build();
408 new TransportZoneBuilder().setKey(new TransportZoneKey(tz))
409 .setTunnelType(TunnelTypeVxlan.class).setSubnets(subnetList).setZoneName(tz)
412 LOG.debug("tzone object" + transportZone);
413 transportZoneArrayList.add(transportZone);
415 transportZonesBuilt = new TransportZonesBuilder().setTransportZone(transportZoneArrayList).build();
416 InstanceIdentifier<TransportZones> path = InstanceIdentifier.builder(TransportZones.class).build();
417 LOG.debug("InstanceIdentifier" + path);
418 ItmUtils.asyncUpdate(LogicalDatastoreType.CONFIGURATION, path, transportZonesBuilt, dataBroker,
419 ItmUtils.DEFAULT_CALLBACK);
420 LOG.debug("wrote to Config DS" + transportZonesBuilt);
421 transportZonesHashMap.clear();
422 transportZoneArrayList.clear();
424 LOG.debug("Everything cleared");
426 LOG.debug("NO vteps were configured");
428 } catch (Exception e) {
429 LOG.error(e.getMessage());
433 @SuppressWarnings("checkstyle:RegexpSinglelineJava")
434 public void showTeps(boolean monitorEnabled, int monitorInterval, CommandSession session) throws TepException {
435 boolean flag = false;
436 InstanceIdentifier<TransportZones> path = InstanceIdentifier.builder(TransportZones.class).build();
437 Optional<TransportZones> transportZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
439 if (transportZonesOptional.isPresent()) {
440 TransportZones transportZones = transportZonesOptional.get();
441 if (transportZones.getTransportZone() == null || transportZones.getTransportZone().isEmpty()) {
442 handleError("No teps configured", session);
445 List<String> result = new ArrayList<>();
446 result.add(String.format("Tunnel Monitoring (for VXLAN tunnels): %s", monitorEnabled ? "On" : "Off"));
447 result.add(String.format("Tunnel Monitoring Interval (for VXLAN tunnels): %d", monitorInterval));
448 result.add(System.lineSeparator());
449 result.add(String.format("%-16s %-16s %-16s %-12s %-12s %-12s %-16s %-12s", "TransportZone",
450 "TunnelType", "SubnetMask", "GatewayIP", "VlanID", "DpnID", "IPAddress", "PortName"));
451 result.add("---------------------------------------------------------------------------------------------"
452 + "---------------------------------");
453 for (TransportZone tz : transportZones.getTransportZone()) {
454 if (tz.getSubnets() == null || tz.getSubnets().isEmpty()) {
455 LOG.error("Transport Zone " + tz.getZoneName() + "has no subnets");
458 for (Subnets sub : tz.getSubnets()) {
459 if (sub.getVteps() == null || sub.getVteps().isEmpty()) {
460 LOG.error("Transport Zone " + tz.getZoneName() + "subnet " + sub.getPrefix() + "has no vteps");
463 for (Vteps vtep : sub.getVteps()) {
465 String strTunnelType ;
466 if (tz.getTunnelType().equals(TunnelTypeGre.class)) {
467 strTunnelType = ITMConstants.TUNNEL_TYPE_GRE;
469 strTunnelType = ITMConstants.TUNNEL_TYPE_VXLAN;
471 result.add(String.format("%-16s %-16s %-16s %-12s %-12s %-12s %-16s %-12s",
472 tz.getZoneName(), strTunnelType, new String(sub.getPrefix().getValue()),
473 new String(sub.getGatewayIp().getValue()), sub.getVlanId().toString(),
474 vtep.getDpnId().toString(), new String(vtep.getIpAddress().getValue()),
475 vtep.getPortname()));
479 if (session != null) {
481 for (String print : result) {
482 System.out.println(print);
485 System.out.println("No teps to display");
488 } else if (session != null) {
489 System.out.println("No teps configured");
493 @SuppressWarnings("checkstyle:RegexpSinglelineJava")
494 public void showCache(String cacheName) {
496 if (!DataStoreCache.isCacheValid(cacheName)) {
497 System.out.println(" " + cacheName + " is not a valid Cache Name ");
500 List<Object> keys = null;
501 keys = DataStoreCache.getKeys(cacheName);
502 if (keys != null && !keys.isEmpty()) {
503 System.out.println("Dumping the data in cache for " + cacheName);
504 for (Object key : keys) {
505 System.out.println(" KEY: " + key + " Value: " + DataStoreCache.get(cacheName, key));
506 System.out.println();
509 System.out.println("No data in cache for " + cacheName);
513 @SuppressWarnings("checkstyle:IllegalCatch")
514 public void deleteVtep(BigInteger dpnId, String portName, Integer vlanId, String ipAddress, String subnetMask,
515 String gatewayIp, String transportZone, CommandSession session) throws TepException {
517 IpAddress ipAddressObj = null;
518 IpAddress gatewayIpObj = null;
519 IpPrefix subnetMaskObj = null;
520 final VtepsKey vtepkey = new VtepsKey(dpnId, portName);
522 ipAddressObj = new IpAddress(ipAddress.toCharArray());
523 gatewayIpObj = new IpAddress("0.0.0.0".toCharArray());
524 if (gatewayIp != null) {
525 gatewayIpObj = new IpAddress(gatewayIp.toCharArray());
527 LOG.debug("gateway is null");
529 } catch (Exception e) {
530 handleError("Invalid IpAddress. Expected: 1.0.0.0 to 254.255.255.255", session);
534 subnetMaskObj = new IpPrefix(subnetMask.toCharArray());
535 } catch (Exception e) {
536 handleError("Invalid Subnet Mask. Expected: 0.0.0.0/0 to 255.255.255.255/32", session);
540 if (!validateIPs(ipAddress, subnetMask, gatewayIp)) {
541 handleError("IpAddress and gateWayIp should belong to the subnet provided", session);
544 SubnetsKey subnetsKey = new SubnetsKey(subnetMaskObj);
545 Vteps vtepCli = null;
546 Subnets subCli = null;
548 InstanceIdentifier<Vteps> vpath = InstanceIdentifier.builder(TransportZones.class)
549 .child(TransportZone.class, new TransportZoneKey(transportZone)).child(Subnets.class, subnetsKey)
550 .child(Vteps.class, vtepkey).build();
552 // check if present in tzones and delete from cache
553 boolean existsInCache = isInCache(dpnId, portName, vlanId, ipAddress, subnetMask, gatewayIp,
554 transportZone, session);
555 if (!existsInCache) {
556 Optional<Vteps> vtepOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, vpath, dataBroker);
557 if (vtepOptional.isPresent()) {
558 vtepCli = vtepOptional.get();
559 if (vtepCli.getIpAddress().equals(ipAddressObj)) {
560 InstanceIdentifier<Subnets> spath =
562 .builder(TransportZones.class)
563 .child(TransportZone.class, new TransportZoneKey(transportZone))
564 .child(Subnets.class, subnetsKey).build();
565 Optional<Subnets> subOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, spath,
567 if (subOptional.isPresent()) {
568 subCli = subOptional.get();
569 if (subCli.getGatewayIp().equals(gatewayIpObj) && subCli.getVlanId().equals(vlanId)) {
570 vtepDelCommitList.add(vtepCli);
571 } else if (session != null) {
572 session.getConsole().println("vtep with this vlan or gateway doesnt exist");
575 } else if (session != null) {
576 session.getConsole().println("Vtep with this ipaddress doesnt exist");
578 } else if (session != null) {
579 session.getConsole().println("Vtep Doesnt exist");
584 @SuppressWarnings("checkstyle:IllegalCatch")
585 public <T extends DataObject> void deleteOnCommit() {
586 List<InstanceIdentifier<T>> vtepPaths = new ArrayList<>();
587 List<InstanceIdentifier<T>> subnetPaths = new ArrayList<>();
588 List<InstanceIdentifier<T>> tzPaths = new ArrayList<>();
589 List<Subnets> subDelList = new ArrayList<>();
590 List<TransportZone> tzDelList = new ArrayList<>();
591 List<Vteps> vtepDelList = new ArrayList<>();
592 List<InstanceIdentifier<T>> allPaths = new ArrayList<>();
594 if (vtepDelCommitList != null && !vtepDelCommitList.isEmpty()) {
595 InstanceIdentifier<TransportZones> path = InstanceIdentifier.builder(TransportZones.class).build();
596 Optional<TransportZones> transportZonesOptional =
597 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
598 if (transportZonesOptional.isPresent()) {
599 TransportZones transportZones = transportZonesOptional.get();
600 for (TransportZone tz : transportZones.getTransportZone()) {
601 if (tz.getSubnets() == null || tz.getSubnets().isEmpty()) {
604 for (Subnets sub : tz.getSubnets()) {
605 vtepDelList.addAll(vtepDelCommitList);
606 for (Vteps vtep : vtepDelList) {
607 InstanceIdentifier<T> vpath =
608 (InstanceIdentifier<T>) InstanceIdentifier
609 .builder(TransportZones.class)
610 .child(TransportZone.class, tz.getKey())
611 .child(Subnets.class, sub.getKey())
612 .child(Vteps.class, vtep.getKey()).build();
613 if (sub.getVteps().remove(vtep)) {
614 vtepPaths.add(vpath);
615 if (sub.getVteps().size() == 0 || sub.getVteps() == null) {
624 for (TransportZone tz : transportZones.getTransportZone()) {
625 if (tz.getSubnets() == null || tz.getSubnets().isEmpty()) {
628 for (Subnets sub : subDelList) {
629 if (tz.getSubnets().remove(sub)) {
630 InstanceIdentifier<T> spath =
631 (InstanceIdentifier<T>) InstanceIdentifier
632 .builder(TransportZones.class)
633 .child(TransportZone.class, tz.getKey())
634 .child(Subnets.class, sub.getKey()).build();
635 subnetPaths.add(spath);
636 if (tz.getSubnets() == null || tz.getSubnets().size() == 0) {
643 for (TransportZone tz : tzDelList) {
644 if (transportZones.getTransportZone().remove(tz)) {
645 InstanceIdentifier<T> tpath =
646 (InstanceIdentifier<T>) InstanceIdentifier.builder(TransportZones.class)
647 .child(TransportZone.class, tz.getKey()).build();
649 if (transportZones.getTransportZone() == null
650 || transportZones.getTransportZone().size() == 0) {
651 MDSALDataStoreUtils.asyncRemove(dataBroker, LogicalDatastoreType.CONFIGURATION,
652 path, ItmUtils.DEFAULT_CALLBACK);
657 allPaths.addAll(vtepPaths);
658 allPaths.addAll(subnetPaths);
659 allPaths.addAll(tzPaths);
660 ItmUtils.asyncBulkRemove(dataBroker, LogicalDatastoreType.CONFIGURATION, allPaths,
661 ItmUtils.DEFAULT_CALLBACK);
667 vtepDelCommitList.clear();
669 } catch (Exception e) {
670 LOG.error(e.getMessage());
674 @SuppressWarnings("checkstyle:RegexpSinglelineJava")
675 public void showState(List<StateTunnelList> tunnelLists, boolean tunnelMonitorEnabled,
676 CommandSession session) throws TepException {
677 if (tunnelLists == null || tunnelLists.isEmpty()) {
678 handleError("No Internal Tunnels Exist", session);
681 if (!tunnelMonitorEnabled) {
682 if (session != null) {
683 session.getConsole().println("Tunnel Monitoring is Off");
686 String displayFormat = "%-16s %-16s %-16s %-16s %-16s %-10s %-10s";
687 System.out.println(String.format(displayFormat, "Tunnel Name", "Source-DPN",
688 "Destination-DPN", "Source-IP", "Destination-IP", "Trunk-State", "Transport Type"));
689 System.out.println("-----------------------------------------------------------------------------------------"
690 + "--------------------------------------------");
692 for (StateTunnelList tunnelInst : tunnelLists) {
693 // Display only the internal tunnels
694 if (tunnelInst.getDstInfo().getTepDeviceType().equals(TepTypeInternal.class)) {
695 String tunnelInterfaceName = tunnelInst.getTunnelInterfaceName();
696 LOG.trace("tunnelInterfaceName::: {}", tunnelInterfaceName);
697 String tunnelState = ITMConstants.TUNNEL_STATE_UNKNOWN;
698 if (tunnelInst.getOperState() == TunnelOperStatus.Up) {
699 tunnelState = ITMConstants.TUNNEL_STATE_UP;
700 } else if (tunnelInst.getOperState() == TunnelOperStatus.Down) {
701 tunnelState = ITMConstants.TUNNEL_STATE_DOWN;
703 Class<? extends TunnelTypeBase> tunType = tunnelInst.getTransportType();
704 String tunnelType = ITMConstants.TUNNEL_TYPE_VXLAN;
705 if (tunType.equals(TunnelTypeVxlan.class)) {
706 tunnelType = ITMConstants.TUNNEL_TYPE_VXLAN;
707 } else if (tunType.equals(TunnelTypeGre.class)) {
708 tunnelType = ITMConstants.TUNNEL_TYPE_GRE;
709 } else if (tunType.equals(TunnelTypeMplsOverGre.class)) {
710 tunnelType = ITMConstants.TUNNEL_TYPE_MPLSoGRE;
712 System.out.println(String.format(displayFormat, tunnelInst.getTunnelInterfaceName(),
713 tunnelInst.getSrcInfo().getTepDeviceId(), tunnelInst.getDstInfo().getTepDeviceId(),
714 new String(tunnelInst.getSrcInfo().getTepIp().getValue()),
715 new String(tunnelInst.getDstInfo().getTepIp().getValue()), tunnelState, tunnelType));
720 // deletes from ADD-cache if it exists.
721 public boolean isInCache(BigInteger dpnId, String portName, Integer vlanId, String ipAddress, String subnetMask,
722 String gatewayIp, String transportZone, CommandSession session) {
723 boolean exists = false;
724 final VtepsKey vtepkey = new VtepsKey(dpnId, portName);
725 IpAddress ipAddressObj = new IpAddress(ipAddress.toCharArray());
726 IpPrefix subnetMaskObj = new IpPrefix(subnetMask.toCharArray());
727 IpAddress gatewayIpObj = new IpAddress("0.0.0.0".toCharArray());
728 if (gatewayIp != null) {
729 gatewayIpObj = new IpAddress(gatewayIp.toCharArray());
731 LOG.debug("gateway is null");
733 SubnetsKey subnetsKey = new SubnetsKey(subnetMaskObj);
734 Vteps vtepCli = new VtepsBuilder().setDpnId(dpnId).setIpAddress(ipAddressObj).setKey(vtepkey)
735 .setPortname(portName).build();
736 SubnetObject subObCli = new SubnetObject(gatewayIpObj, subnetsKey, subnetMaskObj, vlanId);
738 if (transportZonesHashMap.containsKey(transportZone)) {
739 Map<SubnetObject, List<Vteps>> subVtepMapTemp = transportZonesHashMap.get(transportZone);
740 if (subVtepMapTemp.containsKey(subObCli)) { // if Subnet exists
741 List<Vteps> vtepListTemp = subVtepMapTemp.get(subObCli);
742 if (vtepListTemp.contains(vtepCli)) {
743 exists = true; // return true if tzones has vtep
744 vtepListTemp.remove(vtepCli);
745 if (vtepListTemp.size() == 0) {
746 subVtepMapTemp.remove(subObCli);
747 if (subVtepMapTemp.size() == 0) {
748 transportZonesHashMap.remove(transportZone);
751 } else if (session != null) {
752 session.getConsole().println("Vtep " + "has not been configured");
759 public void configureTunnelType(String transportZoneName, String tunnelType) {
760 LOG.debug("configureTunnelType {} for transportZone {}", tunnelType, transportZoneName);
762 TransportZone transportZoneFromConfigDS = ItmUtils.getTransportZoneFromConfigDS(transportZoneName, dataBroker);
763 Class<? extends TunnelTypeBase> tunType;
765 validateTunnelType(transportZoneName, tunnelType, transportZoneFromConfigDS);
766 if (transportZoneFromConfigDS != null) {
767 if (!transportZoneName.equals(ITMConstants.DEFAULT_TRANSPORT_ZONE)) {
768 LOG.debug("Transport zone {} with tunnel type {} already exists. No action required.",
769 transportZoneName, tunnelType);
772 tunnelType = StringUtils.upperCase(tunnelType);
773 tunType = ItmUtils.TUNNEL_TYPE_MAP.get(tunnelType);
774 if (transportZoneFromConfigDS.getTunnelType().equals(tunType)) {
775 // default-TZ already exists and tunnel-type is not changed during
776 // controller restart, then nothing to do now. Just return.
783 tunnelType = StringUtils.upperCase(tunnelType);
784 tunType = ItmUtils.TUNNEL_TYPE_MAP.get(tunnelType);
786 TransportZones transportZones = null;
787 List<TransportZone> tzList = null;
788 InstanceIdentifier<TransportZones> path = InstanceIdentifier.builder(TransportZones.class).build();
789 Optional<TransportZones> tzones = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
791 TransportZone tzone = new TransportZoneBuilder().setKey(new TransportZoneKey(transportZoneName))
792 .setTunnelType(tunType).build();
793 if (tzones.isPresent()) {
794 tzList = tzones.get().getTransportZone();
795 if (tzList == null || tzList.isEmpty()) {
796 tzList = new ArrayList<>();
799 tzList = new ArrayList<>();
802 transportZones = new TransportZonesBuilder().setTransportZone(tzList).build();
803 ItmUtils.syncWrite(LogicalDatastoreType.CONFIGURATION, path, transportZones, dataBroker);
808 * Validate tunnel type.
810 * @param transportZoneName
815 private void validateTunnelType(String transportZoneName, String tunnelType,TransportZone tzoneFromConfigDs) {
817 * String strTunnelType = ItmUtils.validateTunnelType(tunnelType);
819 * TransportZone tZone = getTransportZone(tZoneName); if (tZone != null)
820 * { if (!StringUtils.equalsIgnoreCase(strTunnelType,
821 * tZone.getTunnelType()) && ItmUtils.isNotEmpty(tZone.getSubnets())) {
822 * String errorMsg = new StringBuilder("Changing the tunnel type from "
823 * ).append(tZone.getTunnelType()) .append(" to ").append(strTunnelType)
824 * .append(" is not allowed for already configured transport zone ["
825 * ).append(tZoneName) .append("].").toString();
826 * Preconditions.checkArgument(false, errorMsg); } }
828 String strTunnelType = ItmUtils.validateTunnelType(tunnelType);
829 Class<? extends TunnelTypeBase> tunType;
830 if (strTunnelType.equals(ITMConstants.TUNNEL_TYPE_VXLAN)) {
831 tunType = TunnelTypeVxlan.class;
833 tunType = TunnelTypeGre.class;
835 // TransportZone tZone = getTransportZone(tZoneName);
836 // if (tZone != null) {
837 if (tzoneFromConfigDs != null) {
838 if (!tzoneFromConfigDs.getTunnelType().equals(tunType) && ItmUtils.isNotEmpty(tzoneFromConfigDs
840 // for default-TZ, such error message is not needed to be thrown.
841 // it needs to be handled in different way, by deleting default-TZ
842 // with old tunnel-type and then add default-TZ with new tunnel-type
843 if (!transportZoneName.equals(ITMConstants.DEFAULT_TRANSPORT_ZONE)) {
844 String errorMsg = "Changing the tunnel type from " + tzoneFromConfigDs.getTunnelType()
845 + " to " + strTunnelType
846 + " is not allowed for already configured transport zone [" + transportZoneName
848 Preconditions.checkArgument(false, errorMsg);
850 // delete already existing default TZ
851 ItmUtils.deleteTransportZoneFromConfigDS(ITMConstants.DEFAULT_TRANSPORT_ZONE, dataBroker);
857 public void configureTunnelMonitorParams(boolean monitorEnabled, String monitorProtocol) {
858 InstanceIdentifier<TunnelMonitorParams> path = InstanceIdentifier.builder(TunnelMonitorParams.class).build();
859 Optional<TunnelMonitorParams> storedTunnelMonitor = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
861 Class<? extends TunnelMonitoringTypeBase> monitorType ;
862 if (storedTunnelMonitor.isPresent() && storedTunnelMonitor.get().getMonitorProtocol() != null) {
863 monitorType = storedTunnelMonitor.get().getMonitorProtocol();
865 if (monitorProtocol != null && monitorProtocol.equalsIgnoreCase(ITMConstants.MONITOR_TYPE_LLDP)) {
866 monitorType = TunnelMonitoringTypeLldp.class;
868 monitorType = TunnelMonitoringTypeBfd.class;
871 if (!storedTunnelMonitor.isPresent() || storedTunnelMonitor.get().isEnabled() != monitorEnabled) {
872 TunnelMonitorParams tunnelMonitor = new TunnelMonitorParamsBuilder().setEnabled(monitorEnabled)
873 .setMonitorProtocol(monitorType).build();
874 ItmUtils.asyncUpdate(LogicalDatastoreType.CONFIGURATION, path, tunnelMonitor, dataBroker,
875 ItmUtils.DEFAULT_CALLBACK);
880 public void configureTunnelMonitorInterval(int interval) {
881 InstanceIdentifier<TunnelMonitorInterval> path =
882 InstanceIdentifier.builder(TunnelMonitorInterval.class).build();
883 Optional<TunnelMonitorInterval> storedTunnelMonitor = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path,
885 if (!storedTunnelMonitor.isPresent() || storedTunnelMonitor.get().getInterval() != interval) {
886 TunnelMonitorInterval tunnelMonitor = new TunnelMonitorIntervalBuilder().setInterval(interval).build();
887 ItmUtils.asyncUpdate(LogicalDatastoreType.CONFIGURATION, path, tunnelMonitor, dataBroker,
888 ItmUtils.DEFAULT_CALLBACK);
892 public void handleError(String errorMessage, CommandSession session) throws TepException {
893 if (session != null) {
894 session.getConsole().println(errorMessage);
896 throw new TepException(errorMessage);