2 * Copyright (c) 2016 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.TunnelMonitorInterval;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.TunnelMonitorIntervalBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.TunnelMonitorParams;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.TunnelMonitorParamsBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeInternal;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelOperStatus;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelList;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZones;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZonesBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZone;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZoneBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZoneKey;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.Subnets;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.SubnetsBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.SubnetsKey;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.Vteps;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.VtepsBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.VtepsKey;
57 import org.opendaylight.yangtools.yang.binding.DataObject;
58 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
59 import org.slf4j.Logger;
60 import org.slf4j.LoggerFactory;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.ItmConfig;
65 public class TepCommandHelper {
67 private static final Logger LOG = LoggerFactory.getLogger(TepCommandHelper.class);
68 private final DataBroker dataBroker;
69 private final ItmConfig itmConfig;
71 static short flag = 0;
73 * boolean flag add_or_delete --- can be set to true if the last called tep
74 * command is Tep-add else set to false when Tep-delete is called
75 * tepCommandHelper object is created only once in session initiated
77 final Map<String, Map<SubnetObject, List<Vteps>>> tZones = new HashMap<>();
78 private List<Subnets> subnetList = new ArrayList<>();
79 private List<TransportZone> tZoneList = new ArrayList<>();
80 private List<Vteps> vtepDelCommitList = new ArrayList<>();
82 // private List<InstanceIdentifier<? extends DataObject>> vtepPaths = new
86 public TepCommandHelper(final DataBroker dataBroker, final ItmConfig itmConfig) {
87 this.dataBroker = dataBroker;
88 this.itmConfig = itmConfig;
92 public void start() throws Exception {
93 boolean defTzEnabled = itmConfig.isDefTzEnabled();
95 String tunnelType = itmConfig.getDefTzTunnelType();
96 if (tunnelType == null || tunnelType.isEmpty()) {
97 tunnelType = ITMConstants.TUNNEL_TYPE_VXLAN;
99 configureTunnelType(ITMConstants.DEFAULT_TRANSPORT_ZONE, tunnelType);
100 LOG.debug("{} is created with {} tunnel-type.", ITMConstants.DEFAULT_TRANSPORT_ZONE, tunnelType);
102 LOG.debug("Removing {} on start-up, def-tz-enabled is false.", ITMConstants.DEFAULT_TRANSPORT_ZONE);
103 // check if default-TZ already exists, then delete it because flag is OFF now.
104 ItmUtils.deleteTransportZoneFromConfigDS(ITMConstants.DEFAULT_TRANSPORT_ZONE, dataBroker);
106 LOG.info("TepCommandHelper Started");
110 public void close() {
111 LOG.info("TepCommandHelper Closed");
114 public void createLocalCache(BigInteger dpnId, String portName, Integer vlanId, String ipAddress,
115 String subnetMask, String gatewayIp, String transportZone, CommandSession session) throws TepException{
118 IpAddress ipAddressObj = null;
119 IpAddress gatewayIpObj = null;
120 IpPrefix subnetMaskObj = null;
121 VtepsKey vtepkey = new VtepsKey(dpnId, portName);
123 ipAddressObj = new IpAddress(ipAddress.toCharArray());
124 gatewayIpObj = new IpAddress("0.0.0.0".toCharArray());
125 if (gatewayIp != null) {
126 gatewayIpObj = new IpAddress(gatewayIp.toCharArray());
128 LOG.debug("gateway is null");
130 } catch (Exception e) {
131 handleError("Invalid IpAddress. Expected: 1.0.0.0 to 254.255.255.255", session);
135 subnetMaskObj = new IpPrefix(subnetMask.toCharArray());
136 } catch (Exception e) {
137 handleError("Invalid Subnet Mask. Expected: 0.0.0.0/0 to 255.255.255.255/32", session);
141 if (!validateIPs(ipAddress, subnetMask, gatewayIp)) {
142 handleError("IpAddress and gateWayIp should belong to the subnet provided", session);
146 if (checkTepPerTzPerDpn(transportZone, dpnId)) {
147 if(session != null) {
148 session.getConsole().println("Only one end point per transport Zone per Dpn is allowed");
152 Vteps vtepCli = new VtepsBuilder().setDpnId(dpnId).setIpAddress(ipAddressObj).setKey(vtepkey)
153 .setPortname(portName).build();
154 validateForDuplicates(vtepCli, transportZone);
156 SubnetsKey subnetsKey = new SubnetsKey(subnetMaskObj);
157 SubnetObject subObCli = new SubnetObject(gatewayIpObj, subnetsKey, subnetMaskObj, vlanId);
158 if (tZones.containsKey(transportZone)) {
159 Map<SubnetObject, List<Vteps>> subVtepMapTemp = tZones.get(transportZone);
160 if (subVtepMapTemp.containsKey(subObCli)) { // if Subnet exists
161 List<Vteps> vtepListTemp = subVtepMapTemp.get(subObCli);
162 if (vtepListTemp.contains(vtepCli)) {
165 vtepListTemp.add(vtepCli);
167 } else { // subnet doesnt exist
168 if (checkExistingSubnet(subVtepMapTemp, subObCli)) {
169 if(session != null) {
170 session.getConsole().println("subnet with subnet mask " + subObCli.get_key() + "already exists");
174 List<Vteps> vtepListTemp = new ArrayList<>();
175 vtepListTemp.add(vtepCli);
176 subVtepMapTemp.put(subObCli, vtepListTemp);
179 List<Vteps> vtepListTemp = new ArrayList<>();
180 vtepListTemp.add(vtepCli);
181 Map<SubnetObject, List<Vteps>> subVtepMapTemp = new HashMap<>();
182 subVtepMapTemp.put(subObCli, vtepListTemp);
183 tZones.put(transportZone, subVtepMapTemp);
187 private boolean validateIPs(String ipAddress, String subnetMask, String gatewayIp) {
188 SubnetUtils utils = new SubnetUtils(subnetMask);
189 if ((utils.getInfo().isInRange(ipAddress)) && ((gatewayIp == null) || (utils.getInfo().isInRange(gatewayIp)))) {
192 LOG.trace("InValid IP");
198 * Validate for duplicates.
202 * @param transportZone
205 public void validateForDuplicates(Vteps inputVtep, String transportZone) {
206 Map<String, TransportZone> tZoneMap = getAllTransportZonesAsMap();
208 boolean isConfiguredTepGreType = isGreTunnelType(transportZone, tZoneMap);
209 // Checking for duplicates in local cache
210 for (String tZ : tZones.keySet()) {
211 boolean isGreType = isGreTunnelType(tZ, tZoneMap);
212 Map<SubnetObject, List<Vteps>> subVtepMapTemp = tZones.get(tZ);
213 for (SubnetObject subOb : subVtepMapTemp.keySet()) {
214 List<Vteps> vtepList = subVtepMapTemp.get(subOb);
215 validateForDuplicateAndSingleGreTep(inputVtep, isConfiguredTepGreType, isGreType, vtepList);
218 // Checking for duplicates in config DS
219 for (TransportZone tZ : tZoneMap.values()) {
220 boolean isGreType = false;
221 if (tZ.getTunnelType().equals(TunnelTypeGre.class)) {
224 for (Subnets sub : ItmUtils.emptyIfNull(tZ.getSubnets())) {
225 List<Vteps> vtepList = sub.getVteps();
226 validateForDuplicateAndSingleGreTep(inputVtep, isConfiguredTepGreType, isGreType, vtepList);
231 private void validateForDuplicateAndSingleGreTep(Vteps inputVtep, boolean isConfiguredTepGreType, boolean isGreType,
232 List<Vteps> vtepList) {
233 if (ItmUtils.isEmpty(vtepList)) {
236 if (vtepList.contains(inputVtep)) {
237 Preconditions.checkArgument(false, "VTEP already exists");
239 BigInteger dpnId = inputVtep.getDpnId();
240 if (isConfiguredTepGreType && isGreType) {
241 for (Vteps vtep : vtepList) {
242 if (vtep.getDpnId().equals(dpnId)) {
243 String errMsg = "DPN [" + dpnId +
244 "] already configured with GRE TEP. Mutiple GRE TEP's on a single DPN are not allowed.";
245 Preconditions.checkArgument(false, errMsg);
252 * Gets all transport zones as map.
254 * @return all transport zones as map
256 private Map<String, TransportZone> getAllTransportZonesAsMap() {
257 TransportZones tZones = getAllTransportZones();
258 Map<String, TransportZone> tZoneMap = new HashMap<>();
259 if( null != tZones) {
260 for (TransportZone tzone : ItmUtils.emptyIfNull(tZones.getTransportZone())) {
261 tZoneMap.put(tzone.getZoneName(), tzone);
268 * Checks if is gre tunnel type.
274 * @return true, if is gre tunnel type
276 private boolean isGreTunnelType(String tZoneName, Map<String, TransportZone> tZoneMap) {
277 TransportZone tzone = tZoneMap.get(tZoneName);
279 if (tzone != null && StringUtils.equalsIgnoreCase(ITMConstants.TUNNEL_TYPE_GRE, tzone.getTunnelType())) {
283 return (tzone != null) && (tzone.getTunnelType()).equals(TunnelTypeGre.class);
287 * Gets the transport zone.
291 * @return the transport zone
293 public TransportZone getTransportZone(String tzone) {
294 InstanceIdentifier<TransportZone> tzonePath = InstanceIdentifier.builder(TransportZones.class)
295 .child(TransportZone.class, new TransportZoneKey(tzone)).build();
296 return ItmUtils.read(LogicalDatastoreType.CONFIGURATION, tzonePath, dataBroker).orNull();
300 * Gets all transport zones.
302 * @return all transport zones
304 public TransportZones getAllTransportZones() {
305 InstanceIdentifier<TransportZones> path = InstanceIdentifier.builder(TransportZones.class).build();
306 return ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker).orNull();
309 public boolean checkExistingSubnet(Map<SubnetObject, List<Vteps>> subVtepMapTemp, SubnetObject subObCli) {
310 for (SubnetObject subOb : subVtepMapTemp.keySet()) {
311 if (subOb.get_key().equals(subObCli.get_key())) {
312 if (!(subOb.get_vlanId().equals(subObCli.get_vlanId())))
314 if (!(subOb.get_gatewayIp().equals(subObCli.get_gatewayIp())))
321 public boolean checkTepPerTzPerDpn(String tzone, BigInteger dpnId) {
322 // check in local cache
323 if (tZones.containsKey(tzone)) {
324 Map<SubnetObject, List<Vteps>> subVtepMapTemp = tZones.get(tzone);
325 for (SubnetObject subOb : subVtepMapTemp.keySet()) {
326 List<Vteps> vtepList = subVtepMapTemp.get(subOb);
327 for (Vteps vtep : vtepList)
328 if (vtep.getDpnId().equals(dpnId))
334 InstanceIdentifier<TransportZone> tzonePath =
335 InstanceIdentifier.builder(TransportZones.class)
336 .child(TransportZone.class, new TransportZoneKey(tzone)).build();
337 Optional<TransportZone> tZoneOptional =
338 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, tzonePath, dataBroker);
339 if (tZoneOptional.isPresent()) {
340 TransportZone tz = tZoneOptional.get();
341 if (tz.getSubnets() == null || tz.getSubnets().isEmpty())
343 for (Subnets sub : tz.getSubnets()) {
344 if (sub.getVteps() == null || sub.getVteps().isEmpty())
346 for (Vteps vtep : sub.getVteps()) {
347 if (vtep.getDpnId().equals(dpnId)) {
356 public void buildTeps() {
357 TransportZones tZonesBuilt = null;
358 TransportZone tZone = null;
360 LOG.debug("no of teps added" + check);
361 if (tZones != null || !tZones.isEmpty()) {
362 tZoneList = new ArrayList<>();
363 for (String tZ : tZones.keySet()) {
364 LOG.debug("tZones" + tZ);
365 subnetList = new ArrayList<>();
366 Map<SubnetObject, List<Vteps>> subVtepMapTemp = tZones.get(tZ);
367 for (SubnetObject subOb : subVtepMapTemp.keySet()) {
368 LOG.debug("subnets" + subOb.get_prefix());
369 List<Vteps> vtepList = subVtepMapTemp.get(subOb);
371 new SubnetsBuilder().setGatewayIp(subOb.get_gatewayIp())
372 .setKey(subOb.get_key()).setPrefix(subOb.get_prefix())
373 .setVlanId(subOb.get_vlanId()).setVteps(vtepList).build();
374 subnetList.add(subnet);
375 LOG.debug("vteps" + vtepList);
377 InstanceIdentifier<TransportZone> tZonepath =
378 InstanceIdentifier.builder(TransportZones.class)
379 .child(TransportZone.class, new TransportZoneKey(tZ)).build();
380 Optional<TransportZone> tZoneOptional =
381 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, tZonepath, dataBroker);
382 LOG.debug("read container from DS");
383 if (tZoneOptional.isPresent()) {
384 TransportZone tzoneFromDs = tZoneOptional.get();
385 LOG.debug("read tzone container" + tzoneFromDs.toString());
386 if (tzoneFromDs.getTunnelType() == null
387 || (tzoneFromDs.getTunnelType()).equals(TunnelTypeVxlan.class)) {
389 new TransportZoneBuilder().setKey(new TransportZoneKey(tZ))
390 .setTunnelType(TunnelTypeVxlan.class).setSubnets(subnetList)
391 .setZoneName(tZ).build();
392 } else if ((tzoneFromDs.getTunnelType()).equals(TunnelTypeGre.class)) {
394 new TransportZoneBuilder().setKey(new TransportZoneKey(tZ))
395 .setTunnelType(TunnelTypeGre.class).setSubnets(subnetList)
396 .setZoneName(tZ).build();
400 new TransportZoneBuilder().setKey(new TransportZoneKey(tZ))
401 .setTunnelType(TunnelTypeVxlan.class).setSubnets(subnetList).setZoneName(tZ)
404 LOG.debug("tzone object" + tZone);
405 tZoneList.add(tZone);
407 tZonesBuilt = new TransportZonesBuilder().setTransportZone(tZoneList).build();
408 InstanceIdentifier<TransportZones> path = InstanceIdentifier.builder(TransportZones.class).build();
409 LOG.debug("InstanceIdentifier" + path);
410 ItmUtils.asyncUpdate(LogicalDatastoreType.CONFIGURATION, path, tZonesBuilt, dataBroker,
411 ItmUtils.DEFAULT_CALLBACK);
412 LOG.debug("wrote to Config DS" + tZonesBuilt);
416 LOG.debug("Everything cleared");
418 LOG.debug("NO vteps were configured");
420 } catch (Exception e) {
421 LOG.error(e.getMessage());
425 public void showTeps(boolean monitorEnabled, int monitorInterval, CommandSession session) throws TepException {
426 boolean flag = false;
427 InstanceIdentifier<TransportZones> path = InstanceIdentifier.builder(TransportZones.class).build();
428 Optional<TransportZones> tZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
429 if (tZonesOptional.isPresent()) {
430 TransportZones tZones = tZonesOptional.get();
431 if(tZones.getTransportZone() == null || tZones.getTransportZone().isEmpty())
433 handleError("No teps configured", session);
436 List<String> result = new ArrayList<>();
437 result.add(String.format("Tunnel Monitoring (for VXLAN tunnels): %s", (monitorEnabled ? "On" : "Off")));
438 result.add(String.format("Tunnel Monitoring Interval (for VXLAN tunnels): %d", monitorInterval));
439 result.add(System.lineSeparator());
440 result.add(String.format("%-16s %-16s %-16s %-12s %-12s %-12s %-16s %-12s", "TransportZone", "TunnelType", "SubnetMask",
441 "GatewayIP", "VlanID", "DpnID", "IPAddress", "PortName"));
442 result.add("------------------------------------------------------------------------------------------------------------------------------");
443 for (TransportZone tZ : tZones.getTransportZone()) {
444 if (tZ.getSubnets() == null || tZ.getSubnets().isEmpty()) {
445 LOG.error("Transport Zone " + tZ.getZoneName() + "has no subnets");
448 for (Subnets sub : tZ.getSubnets()) {
449 if (sub.getVteps() == null || sub.getVteps().isEmpty()) {
450 LOG.error("Transport Zone " + tZ.getZoneName() + "subnet " + sub.getPrefix() + "has no vteps");
453 for (Vteps vtep : sub.getVteps()) {
455 String strTunnelType ;
456 if( (tZ.getTunnelType()).equals(TunnelTypeGre.class) )
457 strTunnelType = ITMConstants.TUNNEL_TYPE_GRE ;
459 strTunnelType = ITMConstants.TUNNEL_TYPE_VXLAN ;
460 result.add(String.format("%-16s %-16s %-16s %-12s %-12s %-12s %-16s %-12s", tZ.getZoneName(), strTunnelType, sub
461 .getPrefix().getIpv4Prefix().getValue(), sub.getGatewayIp().getIpv4Address()
462 .getValue(), sub.getVlanId().toString(), vtep.getDpnId().toString(), vtep
463 .getIpAddress().getIpv4Address().getValue(), vtep.getPortname()));
467 if (session != null) {
469 for (String p : result) {
470 session.getConsole().println(p);
473 session.getConsole().println("No teps to display");
476 } else if(session != null){
477 session.getConsole().println("No teps configured");
481 public void showCache(String cacheName) {
483 if( !DataStoreCache.isCacheValid(cacheName)) {
484 System.out.println( " " + cacheName + " is not a valid Cache Name ") ;
487 List<Object> keys = null ;
488 keys = DataStoreCache.getKeys(cacheName);
489 if( keys != null && !keys.isEmpty()) {
490 System.out.println( "Dumping the data in cache for " + cacheName ) ;
491 for( Object key : keys ) {
492 System.out.println( " KEY: " + key + " Value: " + DataStoreCache.get(cacheName, key) ) ;
493 System.out.println() ;
497 System.out.println( "No data in cache for " + cacheName ) ;
500 public void deleteVtep(BigInteger dpnId, String portName, Integer vlanId, String ipAddress, String subnetMask,
501 String gatewayIp, String transportZone,CommandSession session) throws TepException {
503 IpAddress ipAddressObj = null;
504 IpAddress gatewayIpObj = null;
505 IpPrefix subnetMaskObj = null;
506 VtepsKey vtepkey = new VtepsKey(dpnId, portName);
508 ipAddressObj = new IpAddress(ipAddress.toCharArray());
509 gatewayIpObj = new IpAddress("0.0.0.0".toCharArray());
510 if (gatewayIp != null) {
511 gatewayIpObj = new IpAddress(gatewayIp.toCharArray());
513 LOG.debug("gateway is null");
515 } catch (Exception e) {
516 handleError("Invalid IpAddress. Expected: 1.0.0.0 to 254.255.255.255", session);
520 subnetMaskObj = new IpPrefix(subnetMask.toCharArray());
521 } catch (Exception e) {
522 handleError("Invalid Subnet Mask. Expected: 0.0.0.0/0 to 255.255.255.255/32", session);
526 if (!validateIPs(ipAddress, subnetMask, gatewayIp)) {
527 handleError("IpAddress and gateWayIp should belong to the subnet provided", session);
530 SubnetsKey subnetsKey = new SubnetsKey(subnetMaskObj);
531 Vteps vtepCli = null;
532 Subnets subCli = null;
534 InstanceIdentifier<Vteps> vpath =
535 InstanceIdentifier.builder(TransportZones.class)
536 .child(TransportZone.class, new TransportZoneKey(transportZone))
537 .child(Subnets.class, subnetsKey).child(Vteps.class, vtepkey).build();
539 // check if present in tzones and delete from cache
540 boolean existsInCache = isInCache(dpnId, portName, vlanId, ipAddress, subnetMask, gatewayIp, transportZone, session);
541 if (!existsInCache) {
542 Optional<Vteps> vtepOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, vpath, dataBroker);
543 if (vtepOptional.isPresent()) {
544 vtepCli = vtepOptional.get();
545 if(vtepCli.getIpAddress().equals(ipAddressObj)){
546 InstanceIdentifier<Subnets> spath =
548 .builder(TransportZones.class)
549 .child(TransportZone.class, new TransportZoneKey(transportZone))
550 .child(Subnets.class, subnetsKey).build();
551 Optional<Subnets> subOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, spath, dataBroker);
552 if (subOptional.isPresent()) {
553 subCli = subOptional.get();
554 if(subCli.getGatewayIp().equals(gatewayIpObj) && subCli.getVlanId().equals(vlanId)){
555 vtepDelCommitList.add(vtepCli);
557 else if(session != null) {
558 session.getConsole().println("vtep with this vlan or gateway doesnt exist");
562 else if(session != null) {
563 session.getConsole().println("Vtep with this ipaddress doesnt exist");
565 } else if(session != null) {
566 session.getConsole().println("Vtep Doesnt exist");
571 public <T extends DataObject> void deleteOnCommit() {
572 List<InstanceIdentifier<T>> vtepPaths = new ArrayList<>();
573 List<InstanceIdentifier<T>> subnetPaths = new ArrayList<>();
574 List<InstanceIdentifier<T>> tzPaths = new ArrayList<>();
575 List<Subnets> subDelList = new ArrayList<>();
576 List<TransportZone> tzDelList = new ArrayList<>();
577 List<Vteps> vtepDelList = new ArrayList<>();
578 List<InstanceIdentifier<T>> allPaths = new ArrayList<>();
580 if (vtepDelCommitList != null && !vtepDelCommitList.isEmpty()) {
581 InstanceIdentifier<TransportZones> path = InstanceIdentifier.builder(TransportZones.class).build();
582 Optional<TransportZones> tZonesOptional =
583 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
584 if (tZonesOptional.isPresent()) {
585 TransportZones tZones = tZonesOptional.get();
586 for (TransportZone tZ : tZones.getTransportZone()) {
587 if (tZ.getSubnets() == null || tZ.getSubnets().isEmpty())
589 for (Subnets sub : tZ.getSubnets()) {
590 vtepDelList.addAll(vtepDelCommitList);
591 for (Vteps vtep : vtepDelList) {
592 InstanceIdentifier<T> vpath =
593 (InstanceIdentifier<T>) InstanceIdentifier
594 .builder(TransportZones.class)
595 .child(TransportZone.class, tZ.getKey())
596 .child(Subnets.class, sub.getKey())
597 .child(Vteps.class, vtep.getKey()).build();
598 if (sub.getVteps().remove(vtep)) {
599 vtepPaths.add(vpath);
600 if (sub.getVteps().size() == 0 || sub.getVteps() == null) {
609 for (TransportZone tZ : tZones.getTransportZone()) {
610 if (tZ.getSubnets() == null || tZ.getSubnets().isEmpty())
612 for (Subnets sub : subDelList) {
613 if (tZ.getSubnets().remove(sub)) {
614 InstanceIdentifier<T> spath =
615 (InstanceIdentifier<T>) InstanceIdentifier
616 .builder(TransportZones.class)
617 .child(TransportZone.class, tZ.getKey())
618 .child(Subnets.class, sub.getKey()).build();
619 subnetPaths.add(spath);
620 if (tZ.getSubnets() == null || tZ.getSubnets().size() == 0) {
627 for (TransportZone tZ : tzDelList) {
628 if (tZones.getTransportZone().remove(tZ)) {
629 InstanceIdentifier<T> tpath =
630 (InstanceIdentifier<T>) InstanceIdentifier.builder(TransportZones.class)
631 .child(TransportZone.class, tZ.getKey()).build();
633 if (tZones.getTransportZone() == null || tZones.getTransportZone().size() == 0) {
634 MDSALDataStoreUtils.asyncRemove(dataBroker, LogicalDatastoreType.CONFIGURATION, path,
635 ItmUtils.DEFAULT_CALLBACK);
640 allPaths.addAll(vtepPaths);
641 allPaths.addAll(subnetPaths);
642 allPaths.addAll(tzPaths);
643 ItmUtils.asyncBulkRemove(dataBroker, LogicalDatastoreType.CONFIGURATION, allPaths,
644 ItmUtils.DEFAULT_CALLBACK);
650 vtepDelCommitList.clear();
652 } catch (Exception e) {
653 LOG.error(e.getMessage());
657 public void showState(List<StateTunnelList> tunnelLists, boolean tunnelMonitorEnabled,CommandSession session) throws TepException{
658 if (tunnelLists == null || tunnelLists.isEmpty()) {
659 handleError("No Internal Tunnels Exist", session);
662 if (!tunnelMonitorEnabled) {
663 if(session != null) {
664 session.getConsole().println("Tunnel Monitoring is Off");
667 String displayFormat = "%-16s %-16s %-16s %-16s %-16s %-10s %-10s";
668 session.getConsole().println(String.format(displayFormat, "Tunnel Name", "Source-DPN",
669 "Destination-DPN", "Source-IP", "Destination-IP", "Trunk-State", "Transport Type"));
670 session.getConsole().println("-------------------------------------------------------------------------------------------------------------------------------------");
672 for (StateTunnelList tunnelInst : tunnelLists) {
673 // Display only the internal tunnels
674 if( tunnelInst.getDstInfo().getTepDeviceType().equals(TepTypeInternal.class)) {
675 String tunnelInterfaceName = tunnelInst.getTunnelInterfaceName();
676 LOG.trace("tunnelInterfaceName::: {}", tunnelInterfaceName);
677 String tunnelState = ITMConstants.TUNNEL_STATE_UNKNOWN;
678 if (tunnelInst.getOperState() == TunnelOperStatus.Up)
679 tunnelState = ITMConstants.TUNNEL_STATE_UP;
680 else if (tunnelInst.getOperState() == TunnelOperStatus.Down )
681 tunnelState = ITMConstants.TUNNEL_STATE_DOWN;
682 Class<? extends TunnelTypeBase> tunType = tunnelInst.getTransportType();
683 String tunnelType = ITMConstants.TUNNEL_TYPE_VXLAN;
684 if( tunType.equals(TunnelTypeVxlan.class))
685 tunnelType = ITMConstants.TUNNEL_TYPE_VXLAN ;
686 else if( tunType.equals(TunnelTypeGre.class) )
687 tunnelType = ITMConstants.TUNNEL_TYPE_GRE ;
688 else if (tunType.equals(TunnelTypeMplsOverGre.class))
689 tunnelType = ITMConstants.TUNNEL_TYPE_MPLSoGRE;
690 session.getConsole().println(String.format(displayFormat, tunnelInst.getTunnelInterfaceName(), tunnelInst.getSrcInfo().getTepDeviceId(),
691 tunnelInst.getDstInfo().getTepDeviceId(), tunnelInst.getSrcInfo().getTepIp().getIpv4Address().getValue(), tunnelInst.getDstInfo().getTepIp().getIpv4Address().getValue(), tunnelState,
698 // deletes from ADD-cache if it exists.
699 public boolean isInCache(BigInteger dpnId, String portName, Integer vlanId, String ipAddress, String subnetMask,
700 String gatewayIp, String transportZone, CommandSession session) {
701 boolean exists = false;
702 VtepsKey vtepkey = new VtepsKey(dpnId, portName);
703 IpAddress ipAddressObj = new IpAddress(ipAddress.toCharArray());
704 IpPrefix subnetMaskObj = new IpPrefix(subnetMask.toCharArray());
705 IpAddress gatewayIpObj = new IpAddress("0.0.0.0".toCharArray());
706 if (gatewayIp != null) {
707 gatewayIpObj = new IpAddress(gatewayIp.toCharArray());
709 LOG.debug("gateway is null");
711 SubnetsKey subnetsKey = new SubnetsKey(subnetMaskObj);
713 new VtepsBuilder().setDpnId(dpnId).setIpAddress(ipAddressObj).setKey(vtepkey)
714 .setPortname(portName).build();
715 SubnetObject subObCli = new SubnetObject(gatewayIpObj, subnetsKey, subnetMaskObj, vlanId);
717 if (tZones.containsKey(transportZone)) {
718 Map<SubnetObject, List<Vteps>> subVtepMapTemp = tZones.get(transportZone);
719 if (subVtepMapTemp.containsKey(subObCli)) { // if Subnet exists
720 List<Vteps> vtepListTemp = subVtepMapTemp.get(subObCli);
721 if (vtepListTemp.contains(vtepCli)) {
722 exists = true; // return true if tzones has vtep
723 vtepListTemp.remove(vtepCli);
724 if (vtepListTemp.size() == 0) {
725 subVtepMapTemp.remove(subObCli);
726 if (subVtepMapTemp.size() == 0) {
727 tZones.remove(transportZone);
730 } else if(session != null) {
731 session.getConsole().println("Vtep " + "has not been configured");
738 public void configureTunnelType(String tZoneName, String tunnelType) {
739 LOG.debug("configureTunnelType {} for transportZone {}", tunnelType, tZoneName);
741 TransportZone tZoneFromConfigDS = ItmUtils.getTransportZoneFromConfigDS(tZoneName, dataBroker);
742 Class<? extends TunnelTypeBase> tunType;
744 validateTunnelType(tZoneName, tunnelType, tZoneFromConfigDS);
745 if (tZoneFromConfigDS != null) {
746 if (!tZoneName.equals(ITMConstants.DEFAULT_TRANSPORT_ZONE)) {
748 "Transport zone {} with tunnel type {} already exists. No action required.",
749 tZoneName, tunnelType);
752 tunnelType = StringUtils.upperCase(tunnelType);
753 tunType = ItmUtils.TUNNEL_TYPE_MAP.get(tunnelType);
754 if(tZoneFromConfigDS.getTunnelType().equals(tunType)) {
755 // default-TZ already exists and tunnel-type is not changed during
756 // controller restart, then nothing to do now. Just return.
763 tunnelType = StringUtils.upperCase(tunnelType);
764 tunType = ItmUtils.TUNNEL_TYPE_MAP.get(tunnelType);
766 TransportZones transportZones = null;
767 List<TransportZone> tZoneList = null;
768 InstanceIdentifier<TransportZones> path = InstanceIdentifier.builder(TransportZones.class).build();
769 Optional<TransportZones> tZones = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
771 TransportZone tZone = new TransportZoneBuilder().setKey(new TransportZoneKey(tZoneName))
772 .setTunnelType(tunType).build();
773 if (tZones.isPresent()) {
774 tZoneList = tZones.get().getTransportZone();
775 if(tZoneList == null || tZoneList.isEmpty()) {
776 tZoneList = new ArrayList<>();
779 tZoneList = new ArrayList<>();
781 tZoneList.add(tZone);
782 transportZones = new TransportZonesBuilder().setTransportZone(tZoneList).build();
783 ItmUtils.syncWrite(LogicalDatastoreType.CONFIGURATION, path, transportZones, dataBroker);
788 * Validate tunnel type.
795 private void validateTunnelType(String tZoneName, String tunnelType,TransportZone tZoneFromConfigDS) {
797 String strTunnelType = ItmUtils.validateTunnelType(tunnelType);
799 TransportZone tZone = getTransportZone(tZoneName);
801 if (!StringUtils.equalsIgnoreCase(strTunnelType, tZone.getTunnelType())
802 && ItmUtils.isNotEmpty(tZone.getSubnets())) {
803 String errorMsg = new StringBuilder("Changing the tunnel type from ").append(tZone.getTunnelType())
804 .append(" to ").append(strTunnelType)
805 .append(" is not allowed for already configured transport zone [").append(tZoneName)
806 .append("].").toString();
807 Preconditions.checkArgument(false, errorMsg);
811 String strTunnelType = ItmUtils.validateTunnelType(tunnelType);
812 Class<? extends TunnelTypeBase> tunType ;
813 if( strTunnelType.equals(ITMConstants.TUNNEL_TYPE_VXLAN))
814 tunType = TunnelTypeVxlan.class ;
816 tunType = TunnelTypeGre.class ;
817 //TransportZone tZone = getTransportZone(tZoneName);
818 // if (tZone != null) {
819 if (tZoneFromConfigDS != null) {
820 if( (!tZoneFromConfigDS.getTunnelType().equals(tunType)) && ItmUtils.isNotEmpty(tZoneFromConfigDS.getSubnets())) {
821 // for default-TZ, such error message is not needed to be thrown.
822 // it needs to be handled in different way, by deleting default-TZ
823 // with old tunnel-type and then add default-TZ with new tunnel-type
824 if (!tZoneName.equals(ITMConstants.DEFAULT_TRANSPORT_ZONE)) {
825 String errorMsg = "Changing the tunnel type from " + tZoneFromConfigDS.getTunnelType()
826 + " to " + strTunnelType
827 + " is not allowed for already configured transport zone [" + tZoneName
829 Preconditions.checkArgument(false, errorMsg);
831 // delete already existing default TZ
832 ItmUtils.deleteTransportZoneFromConfigDS(ITMConstants.DEFAULT_TRANSPORT_ZONE, dataBroker);
838 public void configureTunnelMonitorParams(boolean monitorEnabled, String monitorProtocol) {
839 InstanceIdentifier<TunnelMonitorParams> path = InstanceIdentifier.builder(TunnelMonitorParams.class).build();
840 Optional<TunnelMonitorParams> storedTunnelMonitor = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
841 Class<? extends TunnelMonitoringTypeBase> monitorType ;
842 if(storedTunnelMonitor.isPresent() && storedTunnelMonitor.get().getMonitorProtocol()!=null )
843 monitorType = storedTunnelMonitor.get().getMonitorProtocol();
846 if(monitorProtocol!=null && monitorProtocol.equalsIgnoreCase(ITMConstants.MONITOR_TYPE_LLDP))
847 monitorType = TunnelMonitoringTypeLldp.class ;
849 monitorType = TunnelMonitoringTypeBfd.class ;
851 if (!storedTunnelMonitor.isPresent()|| storedTunnelMonitor.get().isEnabled() != monitorEnabled) {
852 TunnelMonitorParams tunnelMonitor = new TunnelMonitorParamsBuilder().setEnabled(monitorEnabled).setMonitorProtocol(monitorType).build();
853 ItmUtils.asyncUpdate(LogicalDatastoreType.CONFIGURATION, path, tunnelMonitor, dataBroker,
854 ItmUtils.DEFAULT_CALLBACK);
859 public void configureTunnelMonitorInterval(int interval) {
860 InstanceIdentifier<TunnelMonitorInterval> path = InstanceIdentifier.builder(TunnelMonitorInterval.class).build();
861 Optional<TunnelMonitorInterval> storedTunnelMonitor = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
862 if (!storedTunnelMonitor.isPresent() || storedTunnelMonitor.get().getInterval() != interval) {
863 TunnelMonitorInterval tunnelMonitor = new TunnelMonitorIntervalBuilder().setInterval(interval).build();
864 ItmUtils.asyncUpdate(LogicalDatastoreType.CONFIGURATION, path, tunnelMonitor, dataBroker,
865 ItmUtils.DEFAULT_CALLBACK);
869 public void handleError(String errorMessage, CommandSession session) throws TepException {
870 if(session != null) {
871 session.getConsole().println(errorMessage);
873 throw new TepException(errorMessage);