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 org.apache.commons.lang3.StringUtils;
18 import org.apache.commons.net.util.SubnetUtils;
19 import org.apache.felix.service.command.CommandSession;
20 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
21 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
22 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
23 import org.opendaylight.genius.itm.globals.ITMConstants;
24 import org.opendaylight.genius.utils.cache.DataStoreCache;
25 import org.opendaylight.genius.itm.impl.ItmUtils;
26 import org.opendaylight.genius.mdsalutil.MDSALDataStoreUtils;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnel;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelMonitoringTypeBase;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelMonitoringTypeBfd;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelMonitoringTypeLldp;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeGre;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeMplsOverGre;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.TunnelMonitorInterval;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.TunnelMonitorIntervalBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.TunnelMonitorParams;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.TunnelMonitorParamsBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeInternal;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelOperStatus;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelList;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnel;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZones;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZonesBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZone;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZoneBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZoneKey;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.Subnets;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.SubnetsBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.SubnetsKey;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.Vteps;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.VtepsBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.VtepsKey;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelList;
61 import org.opendaylight.yangtools.yang.binding.DataObject;
62 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
63 import org.slf4j.Logger;
64 import org.slf4j.LoggerFactory;
66 //import org.opendaylight.genius.interfacemgr.util.OperationalIfmUtil;
69 public class TepCommandHelper {
71 private static final Logger LOG = LoggerFactory.getLogger(TepCommandHelper.class);
72 private DataBroker dataBroker;
74 static short flag = 0;
76 * boolean flag add_or_delete --- can be set to true if the last called tep
77 * command is Tep-add else set to false when Tep-delete is called
78 * tepCommandHelper object is created only once in session initiated
80 final Map<String, Map<SubnetObject, List<Vteps>>> tZones = new HashMap<>();
81 private List<Subnets> subnetList = new ArrayList<>();
82 private List<TransportZone> tZoneList = new ArrayList<>();
83 private List<Vteps> vtepDelCommitList = new ArrayList<>();
84 private IInterfaceManager interfaceManager;
86 // private List<InstanceIdentifier<? extends DataObject>> vtepPaths = new
90 public TepCommandHelper(final DataBroker broker) {
91 this.dataBroker = broker;
95 public void setInterfaceManager(IInterfaceManager interfaceManager) {
96 this.interfaceManager = interfaceManager;
99 public void createLocalCache(BigInteger dpnId, String portName, Integer vlanId, String ipAddress,
100 String subnetMask, String gatewayIp, String transportZone, CommandSession session) throws TepException{
103 IpAddress ipAddressObj = null;
104 IpAddress gatewayIpObj = null;
105 IpPrefix subnetMaskObj = null;
106 VtepsKey vtepkey = new VtepsKey(dpnId, portName);
108 ipAddressObj = new IpAddress(ipAddress.toCharArray());
109 gatewayIpObj = new IpAddress("0.0.0.0".toCharArray());
110 if (gatewayIp != null) {
111 gatewayIpObj = new IpAddress(gatewayIp.toCharArray());
113 LOG.debug("gateway is null");
115 } catch (Exception e) {
116 handleError("Invalid IpAddress. Expected: 1.0.0.0 to 254.255.255.255", session);
120 subnetMaskObj = new IpPrefix(subnetMask.toCharArray());
121 } catch (Exception e) {
122 handleError("Invalid Subnet Mask. Expected: 0.0.0.0/0 to 255.255.255.255/32", session);
126 if (!validateIPs(ipAddress, subnetMask, gatewayIp)) {
127 handleError("IpAddress and gateWayIp should belong to the subnet provided", session);
131 if (checkTepPerTzPerDpn(transportZone, dpnId)) {
132 if(session != null) {
133 session.getConsole().println("Only one end point per transport Zone per Dpn is allowed");
137 Vteps vtepCli = new VtepsBuilder().setDpnId(dpnId).setIpAddress(ipAddressObj).setKey(vtepkey)
138 .setPortname(portName).build();
139 validateForDuplicates(vtepCli, transportZone);
141 SubnetsKey subnetsKey = new SubnetsKey(subnetMaskObj);
142 SubnetObject subObCli = new SubnetObject(gatewayIpObj, subnetsKey, subnetMaskObj, vlanId);
143 if (tZones.containsKey(transportZone)) {
144 Map<SubnetObject, List<Vteps>> subVtepMapTemp = tZones.get(transportZone);
145 if (subVtepMapTemp.containsKey(subObCli)) { // if Subnet exists
146 List<Vteps> vtepListTemp = subVtepMapTemp.get(subObCli);
147 if (vtepListTemp.contains(vtepCli)) {
150 vtepListTemp.add(vtepCli);
152 } else { // subnet doesnt exist
153 if (checkExistingSubnet(subVtepMapTemp, subObCli)) {
154 if(session != null) {
155 session.getConsole().println("subnet with subnet mask " + subObCli.get_key() + "already exists");
159 List<Vteps> vtepListTemp = new ArrayList<>();
160 vtepListTemp.add(vtepCli);
161 subVtepMapTemp.put(subObCli, vtepListTemp);
164 List<Vteps> vtepListTemp = new ArrayList<>();
165 vtepListTemp.add(vtepCli);
166 Map<SubnetObject, List<Vteps>> subVtepMapTemp = new HashMap<>();
167 subVtepMapTemp.put(subObCli, vtepListTemp);
168 tZones.put(transportZone, subVtepMapTemp);
172 private boolean validateIPs(String ipAddress, String subnetMask, String gatewayIp) {
173 SubnetUtils utils = new SubnetUtils(subnetMask);
174 if ((utils.getInfo().isInRange(ipAddress)) && ((gatewayIp == null) || (utils.getInfo().isInRange(gatewayIp)))) {
177 LOG.trace("InValid IP");
183 * Validate for duplicates.
187 * @param transportZone
190 public void validateForDuplicates(Vteps inputVtep, String transportZone) {
191 Map<String, TransportZone> tZoneMap = getAllTransportZonesAsMap();
193 boolean isConfiguredTepGreType = isGreTunnelType(transportZone, tZoneMap);
194 // Checking for duplicates in local cache
195 for (String tZ : tZones.keySet()) {
196 boolean isGreType = isGreTunnelType(tZ, tZoneMap);
197 Map<SubnetObject, List<Vteps>> subVtepMapTemp = tZones.get(tZ);
198 for (SubnetObject subOb : subVtepMapTemp.keySet()) {
199 List<Vteps> vtepList = subVtepMapTemp.get(subOb);
200 validateForDuplicateAndSingleGreTep(inputVtep, isConfiguredTepGreType, isGreType, vtepList);
203 // Checking for duplicates in config DS
204 for (TransportZone tZ : tZoneMap.values()) {
205 boolean isGreType = false;
206 if (tZ.getTunnelType().equals(TunnelTypeGre.class)) {
209 for (Subnets sub : ItmUtils.emptyIfNull(tZ.getSubnets())) {
210 List<Vteps> vtepList = sub.getVteps();
211 validateForDuplicateAndSingleGreTep(inputVtep, isConfiguredTepGreType, isGreType, vtepList);
216 private void validateForDuplicateAndSingleGreTep(Vteps inputVtep, boolean isConfiguredTepGreType, boolean isGreType,
217 List<Vteps> vtepList) {
218 if (ItmUtils.isEmpty(vtepList)) {
221 if (vtepList.contains(inputVtep)) {
222 Preconditions.checkArgument(false, "VTEP already exists");
224 BigInteger dpnId = inputVtep.getDpnId();
225 if (isConfiguredTepGreType && isGreType) {
226 for (Vteps vtep : vtepList) {
227 if (vtep.getDpnId().equals(dpnId)) {
228 String errMsg = "DPN [" + dpnId +
229 "] already configured with GRE TEP. Mutiple GRE TEP's on a single DPN are not allowed.";
230 Preconditions.checkArgument(false, errMsg);
237 * Gets all transport zones as map.
239 * @return all transport zones as map
241 private Map<String, TransportZone> getAllTransportZonesAsMap() {
242 TransportZones tZones = getAllTransportZones();
243 Map<String, TransportZone> tZoneMap = new HashMap<>();
244 if( null != tZones) {
245 for (TransportZone tzone : ItmUtils.emptyIfNull(tZones.getTransportZone())) {
246 tZoneMap.put(tzone.getZoneName(), tzone);
253 * Checks if is gre tunnel type.
259 * @return true, if is gre tunnel type
261 private boolean isGreTunnelType(String tZoneName, Map<String, TransportZone> tZoneMap) {
262 TransportZone tzone = tZoneMap.get(tZoneName);
264 if (tzone != null && StringUtils.equalsIgnoreCase(ITMConstants.TUNNEL_TYPE_GRE, tzone.getTunnelType())) {
268 return (tzone != null) && (tzone.getTunnelType()).equals(TunnelTypeGre.class);
272 * Gets the transport zone.
276 * @return the transport zone
278 public TransportZone getTransportZone(String tzone) {
279 InstanceIdentifier<TransportZone> tzonePath = InstanceIdentifier.builder(TransportZones.class)
280 .child(TransportZone.class, new TransportZoneKey(tzone)).build();
281 Optional<TransportZone> tZoneOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, tzonePath,
283 if (tZoneOptional.isPresent()) {
284 return tZoneOptional.get();
290 * Gets the transport zone from config ds.
294 * @return the transport zone
296 public TransportZone getTransportZoneFromConfigDS(String tzone) {
297 InstanceIdentifier<TransportZone> tzonePath = InstanceIdentifier.builder(TransportZones.class)
298 .child(TransportZone.class, new TransportZoneKey(tzone)).build();
299 Optional<TransportZone> tZoneOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, tzonePath,
301 if (tZoneOptional.isPresent()) {
302 return tZoneOptional.get();
308 * Gets all transport zones.
310 * @return all transport zones
312 public TransportZones getAllTransportZones() {
313 InstanceIdentifier<TransportZones> path = InstanceIdentifier.builder(TransportZones.class).build();
314 Optional<TransportZones> tZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
315 if (tZonesOptional.isPresent()) {
316 return tZonesOptional.get();
321 public boolean checkExistingSubnet(Map<SubnetObject, List<Vteps>> subVtepMapTemp, SubnetObject subObCli) {
322 for (SubnetObject subOb : subVtepMapTemp.keySet()) {
323 if (subOb.get_key().equals(subObCli.get_key())) {
324 if (!(subOb.get_vlanId().equals(subObCli.get_vlanId())))
326 if (!(subOb.get_gatewayIp().equals(subObCli.get_gatewayIp())))
333 public boolean checkTepPerTzPerDpn(String tzone, BigInteger dpnId) {
334 // check in local cache
335 if (tZones.containsKey(tzone)) {
336 Map<SubnetObject, List<Vteps>> subVtepMapTemp = tZones.get(tzone);
337 for (SubnetObject subOb : subVtepMapTemp.keySet()) {
338 List<Vteps> vtepList = subVtepMapTemp.get(subOb);
339 for (Vteps vtep : vtepList)
340 if (vtep.getDpnId().equals(dpnId))
346 InstanceIdentifier<TransportZone> tzonePath =
347 InstanceIdentifier.builder(TransportZones.class)
348 .child(TransportZone.class, new TransportZoneKey(tzone)).build();
349 Optional<TransportZone> tZoneOptional =
350 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, tzonePath, dataBroker);
351 if (tZoneOptional.isPresent()) {
352 TransportZone tz = tZoneOptional.get();
353 if (tz.getSubnets() == null || tz.getSubnets().isEmpty())
355 for (Subnets sub : tz.getSubnets()) {
356 if (sub.getVteps() == null || sub.getVteps().isEmpty())
358 for (Vteps vtep : sub.getVteps()) {
359 if (vtep.getDpnId().equals(dpnId)) {
368 public void buildTeps() {
369 TransportZones tZonesBuilt = null;
370 TransportZone tZone = null;
372 LOG.debug("no of teps added" + check);
373 if (tZones != null || !tZones.isEmpty()) {
374 tZoneList = new ArrayList<>();
375 for (String tZ : tZones.keySet()) {
376 LOG.debug("tZones" + tZ);
377 subnetList = new ArrayList<>();
378 Map<SubnetObject, List<Vteps>> subVtepMapTemp = tZones.get(tZ);
379 for (SubnetObject subOb : subVtepMapTemp.keySet()) {
380 LOG.debug("subnets" + subOb.get_prefix());
381 List<Vteps> vtepList = subVtepMapTemp.get(subOb);
383 new SubnetsBuilder().setGatewayIp(subOb.get_gatewayIp())
384 .setKey(subOb.get_key()).setPrefix(subOb.get_prefix())
385 .setVlanId(subOb.get_vlanId()).setVteps(vtepList).build();
386 subnetList.add(subnet);
387 LOG.debug("vteps" + vtepList);
389 InstanceIdentifier<TransportZone> tZonepath =
390 InstanceIdentifier.builder(TransportZones.class)
391 .child(TransportZone.class, new TransportZoneKey(tZ)).build();
392 Optional<TransportZone> tZoneOptional =
393 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, tZonepath, dataBroker);
394 LOG.debug("read container from DS");
395 if (tZoneOptional.isPresent()) {
396 TransportZone tzoneFromDs = tZoneOptional.get();
397 LOG.debug("read tzone container" + tzoneFromDs.toString());
398 if (tzoneFromDs.getTunnelType() == null
399 || (tzoneFromDs.getTunnelType()).equals(TunnelTypeVxlan.class)) {
401 new TransportZoneBuilder().setKey(new TransportZoneKey(tZ))
402 .setTunnelType(TunnelTypeVxlan.class).setSubnets(subnetList)
403 .setZoneName(tZ).build();
404 } else if ((tzoneFromDs.getTunnelType()).equals(TunnelTypeGre.class)) {
406 new TransportZoneBuilder().setKey(new TransportZoneKey(tZ))
407 .setTunnelType(TunnelTypeGre.class).setSubnets(subnetList)
408 .setZoneName(tZ).build();
412 new TransportZoneBuilder().setKey(new TransportZoneKey(tZ))
413 .setTunnelType(TunnelTypeVxlan.class).setSubnets(subnetList).setZoneName(tZ)
416 LOG.debug("tzone object" + tZone);
417 tZoneList.add(tZone);
419 tZonesBuilt = new TransportZonesBuilder().setTransportZone(tZoneList).build();
420 InstanceIdentifier<TransportZones> path = InstanceIdentifier.builder(TransportZones.class).build();
421 LOG.debug("InstanceIdentifier" + path);
422 ItmUtils.asyncUpdate(LogicalDatastoreType.CONFIGURATION, path, tZonesBuilt, dataBroker,
423 ItmUtils.DEFAULT_CALLBACK);
424 LOG.debug("wrote to Config DS" + tZonesBuilt);
428 LOG.debug("Everything cleared");
430 LOG.debug("NO vteps were configured");
432 } catch (Exception e) {
433 LOG.error(e.getMessage());
437 public void showTeps(boolean monitorEnabled, int monitorInterval, CommandSession session) throws TepException {
438 boolean flag = false;
439 InstanceIdentifier<TransportZones> path = InstanceIdentifier.builder(TransportZones.class).build();
440 Optional<TransportZones> tZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
441 if (tZonesOptional.isPresent()) {
442 TransportZones tZones = tZonesOptional.get();
443 if(tZones.getTransportZone() == null || tZones.getTransportZone().isEmpty())
445 handleError("No teps configured", session);
448 List<String> result = new ArrayList<>();
449 result.add(String.format("Tunnel Monitoring (for VXLAN tunnels): %s", (monitorEnabled ? "On" : "Off")));
450 result.add(String.format("Tunnel Monitoring Interval (for VXLAN tunnels): %d", monitorInterval));
451 result.add(System.lineSeparator());
452 result.add(String.format("%-16s %-16s %-16s %-12s %-12s %-12s %-16s %-12s", "TransportZone", "TunnelType", "SubnetMask",
453 "GatewayIP", "VlanID", "DpnID", "IPAddress", "PortName"));
454 result.add("------------------------------------------------------------------------------------------------------------------------------");
455 for (TransportZone tZ : tZones.getTransportZone()) {
456 if (tZ.getSubnets() == null || tZ.getSubnets().isEmpty()) {
457 LOG.error("Transport Zone " + tZ.getZoneName() + "has no subnets");
460 for (Subnets sub : tZ.getSubnets()) {
461 if (sub.getVteps() == null || sub.getVteps().isEmpty()) {
462 LOG.error("Transport Zone " + tZ.getZoneName() + "subnet " + sub.getPrefix() + "has no vteps");
465 for (Vteps vtep : sub.getVteps()) {
467 String strTunnelType ;
468 if( (tZ.getTunnelType()).equals(TunnelTypeGre.class) )
469 strTunnelType = ITMConstants.TUNNEL_TYPE_GRE ;
471 strTunnelType = ITMConstants.TUNNEL_TYPE_VXLAN ;
472 result.add(String.format("%-16s %-16s %-16s %-12s %-12s %-12s %-16s %-12s", tZ.getZoneName(), strTunnelType, sub
473 .getPrefix().getIpv4Prefix().getValue(), sub.getGatewayIp().getIpv4Address()
474 .getValue(), sub.getVlanId().toString(), vtep.getDpnId().toString(), vtep
475 .getIpAddress().getIpv4Address().getValue(), vtep.getPortname()));
479 if (session != null) {
481 for (String p : result) {
482 session.getConsole().println(p);
485 session.getConsole().println("No teps to display");
488 } else if(session != null){
489 session.getConsole().println("No teps configured");
493 public void showCache(String cacheName) {
495 if( !DataStoreCache.isCacheValid(cacheName)) {
496 System.out.println( " " + cacheName + " is not a valid Cache Name ") ;
499 List<Object> keys = null ;
500 keys = DataStoreCache.getKeys(cacheName);
501 if( keys != null && !keys.isEmpty()) {
502 System.out.println( "Dumping the data in cache for " + cacheName ) ;
503 for( Object key : keys ) {
504 System.out.println( " KEY: " + key + " Value: " + DataStoreCache.get(cacheName, key) ) ;
505 System.out.println() ;
509 System.out.println( "No data in cache for " + cacheName ) ;
512 public void deleteVtep(BigInteger dpnId, String portName, Integer vlanId, String ipAddress, String subnetMask,
513 String gatewayIp, String transportZone,CommandSession session) throws TepException {
515 IpAddress ipAddressObj = null;
516 IpAddress gatewayIpObj = null;
517 IpPrefix subnetMaskObj = null;
518 VtepsKey vtepkey = new VtepsKey(dpnId, portName);
520 ipAddressObj = new IpAddress(ipAddress.toCharArray());
521 gatewayIpObj = new IpAddress("0.0.0.0".toCharArray());
522 if (gatewayIp != null) {
523 gatewayIpObj = new IpAddress(gatewayIp.toCharArray());
525 LOG.debug("gateway is null");
527 } catch (Exception e) {
528 handleError("Invalid IpAddress. Expected: 1.0.0.0 to 254.255.255.255", session);
532 subnetMaskObj = new IpPrefix(subnetMask.toCharArray());
533 } catch (Exception e) {
534 handleError("Invalid Subnet Mask. Expected: 0.0.0.0/0 to 255.255.255.255/32", session);
538 if (!validateIPs(ipAddress, subnetMask, gatewayIp)) {
539 handleError("IpAddress and gateWayIp should belong to the subnet provided", session);
542 SubnetsKey subnetsKey = new SubnetsKey(subnetMaskObj);
543 Vteps vtepCli = null;
544 Subnets subCli = null;
546 InstanceIdentifier<Vteps> vpath =
547 InstanceIdentifier.builder(TransportZones.class)
548 .child(TransportZone.class, new TransportZoneKey(transportZone))
549 .child(Subnets.class, subnetsKey).child(Vteps.class, vtepkey).build();
551 // check if present in tzones and delete from cache
552 boolean existsInCache = isInCache(dpnId, portName, vlanId, ipAddress, subnetMask, gatewayIp, transportZone, session);
553 if (!existsInCache) {
554 Optional<Vteps> vtepOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, vpath, dataBroker);
555 if (vtepOptional.isPresent()) {
556 vtepCli = vtepOptional.get();
557 if(vtepCli.getIpAddress().equals(ipAddressObj)){
558 InstanceIdentifier<Subnets> spath =
560 .builder(TransportZones.class)
561 .child(TransportZone.class, new TransportZoneKey(transportZone))
562 .child(Subnets.class, subnetsKey).build();
563 Optional<Subnets> subOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, spath, dataBroker);
564 if (subOptional.isPresent()) {
565 subCli = subOptional.get();
566 if(subCli.getGatewayIp().equals(gatewayIpObj) && subCli.getVlanId().equals(vlanId)){
567 vtepDelCommitList.add(vtepCli);
569 else if(session != null) {
570 session.getConsole().println("vtep with this vlan or gateway doesnt exist");
574 else if(session != null) {
575 session.getConsole().println("Vtep with this ipaddress doesnt exist");
577 } else if(session != null) {
578 session.getConsole().println("Vtep Doesnt exist");
583 public <T extends DataObject> void deleteOnCommit() {
584 List<InstanceIdentifier<T>> vtepPaths = new ArrayList<>();
585 List<InstanceIdentifier<T>> subnetPaths = new ArrayList<>();
586 List<InstanceIdentifier<T>> tzPaths = new ArrayList<>();
587 List<Subnets> subDelList = new ArrayList<>();
588 List<TransportZone> tzDelList = new ArrayList<>();
589 List<Vteps> vtepDelList = new ArrayList<>();
590 List<InstanceIdentifier<T>> allPaths = new ArrayList<>();
592 if (vtepDelCommitList != null && !vtepDelCommitList.isEmpty()) {
593 InstanceIdentifier<TransportZones> path = InstanceIdentifier.builder(TransportZones.class).build();
594 Optional<TransportZones> tZonesOptional =
595 ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
596 if (tZonesOptional.isPresent()) {
597 TransportZones tZones = tZonesOptional.get();
598 for (TransportZone tZ : tZones.getTransportZone()) {
599 if (tZ.getSubnets() == null || tZ.getSubnets().isEmpty())
601 for (Subnets sub : tZ.getSubnets()) {
602 vtepDelList.addAll(vtepDelCommitList);
603 for (Vteps vtep : vtepDelList) {
604 InstanceIdentifier<T> vpath =
605 (InstanceIdentifier<T>) InstanceIdentifier
606 .builder(TransportZones.class)
607 .child(TransportZone.class, tZ.getKey())
608 .child(Subnets.class, sub.getKey())
609 .child(Vteps.class, vtep.getKey()).build();
610 if (sub.getVteps().remove(vtep)) {
611 vtepPaths.add(vpath);
612 if (sub.getVteps().size() == 0 || sub.getVteps() == null) {
621 for (TransportZone tZ : tZones.getTransportZone()) {
622 if (tZ.getSubnets() == null || tZ.getSubnets().isEmpty())
624 for (Subnets sub : subDelList) {
625 if (tZ.getSubnets().remove(sub)) {
626 InstanceIdentifier<T> spath =
627 (InstanceIdentifier<T>) InstanceIdentifier
628 .builder(TransportZones.class)
629 .child(TransportZone.class, tZ.getKey())
630 .child(Subnets.class, sub.getKey()).build();
631 subnetPaths.add(spath);
632 if (tZ.getSubnets() == null || tZ.getSubnets().size() == 0) {
639 for (TransportZone tZ : tzDelList) {
640 if (tZones.getTransportZone().remove(tZ)) {
641 InstanceIdentifier<T> tpath =
642 (InstanceIdentifier<T>) InstanceIdentifier.builder(TransportZones.class)
643 .child(TransportZone.class, tZ.getKey()).build();
645 if (tZones.getTransportZone() == null || tZones.getTransportZone().size() == 0) {
646 MDSALDataStoreUtils.asyncRemove(dataBroker, LogicalDatastoreType.CONFIGURATION, path,
647 ItmUtils.DEFAULT_CALLBACK);
652 allPaths.addAll(vtepPaths);
653 allPaths.addAll(subnetPaths);
654 allPaths.addAll(tzPaths);
655 ItmUtils.asyncBulkRemove(dataBroker, LogicalDatastoreType.CONFIGURATION, allPaths,
656 ItmUtils.DEFAULT_CALLBACK);
662 vtepDelCommitList.clear();
664 } catch (Exception e) {
665 LOG.error(e.getMessage());
669 public void showState(List<StateTunnelList> tunnelLists, boolean tunnelMonitorEnabled,CommandSession session) throws TepException{
670 if (tunnelLists == null || tunnelLists.isEmpty()) {
671 handleError("No Internal Tunnels Exist", session);
674 if (!tunnelMonitorEnabled) {
675 if(session != null) {
676 session.getConsole().println("Tunnel Monitoring is Off");
679 String displayFormat = "%-16s %-16s %-16s %-16s %-16s %-10s %-10s";
680 session.getConsole().println(String.format(displayFormat, "Tunnel Name", "Source-DPN",
681 "Destination-DPN", "Source-IP", "Destination-IP", "Trunk-State", "Transport Type"));
682 session.getConsole().println("-------------------------------------------------------------------------------------------------------------------------------------");
684 for (StateTunnelList tunnelInst : tunnelLists) {
685 // Display only the internal tunnels
686 if( tunnelInst.getDstInfo().getTepDeviceType().equals(TepTypeInternal.class)) {
687 String tunnelInterfaceName = tunnelInst.getTunnelInterfaceName();
688 LOG.trace("tunnelInterfaceName::: {}", tunnelInterfaceName);
689 String tunnelState = ITMConstants.TUNNEL_STATE_UNKNOWN;
690 if (tunnelInst.getOperState() == TunnelOperStatus.Up)
691 tunnelState = ITMConstants.TUNNEL_STATE_UP;
692 else if (tunnelInst.getOperState() == TunnelOperStatus.Down )
693 tunnelState = ITMConstants.TUNNEL_STATE_DOWN;
694 Class<? extends TunnelTypeBase> tunType = tunnelInst.getTransportType();
695 String tunnelType = ITMConstants.TUNNEL_TYPE_VXLAN;
696 if( tunType.equals(TunnelTypeVxlan.class))
697 tunnelType = ITMConstants.TUNNEL_TYPE_VXLAN ;
698 else if( tunType.equals(TunnelTypeGre.class) )
699 tunnelType = ITMConstants.TUNNEL_TYPE_GRE ;
700 else if (tunType.equals(TunnelTypeMplsOverGre.class))
701 tunnelType = ITMConstants.TUNNEL_TYPE_MPLSoGRE;
702 session.getConsole().println(String.format(displayFormat, tunnelInst.getTunnelInterfaceName(), tunnelInst.getSrcInfo().getTepDeviceId(),
703 tunnelInst.getDstInfo().getTepDeviceId(), tunnelInst.getSrcInfo().getTepIp().getIpv4Address().getValue(), tunnelInst.getDstInfo().getTepIp().getIpv4Address().getValue(), tunnelState,
710 // deletes from ADD-cache if it exists.
711 public boolean isInCache(BigInteger dpnId, String portName, Integer vlanId, String ipAddress, String subnetMask,
712 String gatewayIp, String transportZone, CommandSession session) {
713 boolean exists = false;
714 VtepsKey vtepkey = new VtepsKey(dpnId, portName);
715 IpAddress ipAddressObj = new IpAddress(ipAddress.toCharArray());
716 IpPrefix subnetMaskObj = new IpPrefix(subnetMask.toCharArray());
717 IpAddress gatewayIpObj = new IpAddress("0.0.0.0".toCharArray());
718 if (gatewayIp != null) {
719 gatewayIpObj = new IpAddress(gatewayIp.toCharArray());
721 LOG.debug("gateway is null");
723 SubnetsKey subnetsKey = new SubnetsKey(subnetMaskObj);
725 new VtepsBuilder().setDpnId(dpnId).setIpAddress(ipAddressObj).setKey(vtepkey)
726 .setPortname(portName).build();
727 SubnetObject subObCli = new SubnetObject(gatewayIpObj, subnetsKey, subnetMaskObj, vlanId);
729 if (tZones.containsKey(transportZone)) {
730 Map<SubnetObject, List<Vteps>> subVtepMapTemp = tZones.get(transportZone);
731 if (subVtepMapTemp.containsKey(subObCli)) { // if Subnet exists
732 List<Vteps> vtepListTemp = subVtepMapTemp.get(subObCli);
733 if (vtepListTemp.contains(vtepCli)) {
734 exists = true; // return true if tzones has vtep
735 vtepListTemp.remove(vtepCli);
736 if (vtepListTemp.size() == 0) {
737 subVtepMapTemp.remove(subObCli);
738 if (subVtepMapTemp.size() == 0) {
739 tZones.remove(transportZone);
742 } else if(session != null) {
743 session.getConsole().println("Vtep " + "has not been configured");
750 public void configureTunnelType(String tZoneName, String tunnelType) {
751 LOG.debug("configureTunnelType {} for transportZone {}", tunnelType, tZoneName);
753 TransportZone tZoneFromConfigDS = getTransportZoneFromConfigDS(tZoneName);
754 validateTunnelType(tZoneName, tunnelType,tZoneFromConfigDS);
756 if (tZoneFromConfigDS != null) {
757 LOG.debug("Transport zone {} with tunnel type {} already exists. No action required.", tZoneName,
761 TransportZones transportZones = null;
762 List<TransportZone> tZoneList = null;
763 InstanceIdentifier<TransportZones> path = InstanceIdentifier.builder(TransportZones.class).build();
764 Optional<TransportZones> tZones = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
765 Class<? extends TunnelTypeBase> tunType = TunnelTypeVxlan.class;
766 if( tunnelType.equals(ITMConstants.TUNNEL_TYPE_VXLAN))
767 tunType = TunnelTypeVxlan.class ;
768 else if( tunnelType.equals(ITMConstants.TUNNEL_TYPE_GRE) )
769 tunType = TunnelTypeGre.class ;
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 String errorMsg = "Changing the tunnel type from " + tZoneFromConfigDS.getTunnelType() +
822 " to " + strTunnelType +
823 " is not allowed for already configured transport zone [" + tZoneName +
825 Preconditions.checkArgument(false, errorMsg);
830 public void configureTunnelMonitorParams(boolean monitorEnabled, String monitorProtocol) {
831 InstanceIdentifier<TunnelMonitorParams> path = InstanceIdentifier.builder(TunnelMonitorParams.class).build();
832 Optional<TunnelMonitorParams> storedTunnelMonitor = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
833 Class<? extends TunnelMonitoringTypeBase> monitorType ;
834 if(storedTunnelMonitor.isPresent() && storedTunnelMonitor.get().getMonitorProtocol()!=null )
835 monitorType = storedTunnelMonitor.get().getMonitorProtocol();
838 if(monitorProtocol!=null && monitorProtocol.equalsIgnoreCase(ITMConstants.MONITOR_TYPE_LLDP))
839 monitorType = TunnelMonitoringTypeLldp.class ;
841 monitorType = TunnelMonitoringTypeBfd.class ;
843 if (!storedTunnelMonitor.isPresent()|| storedTunnelMonitor.get().isEnabled() != monitorEnabled) {
844 TunnelMonitorParams tunnelMonitor = new TunnelMonitorParamsBuilder().setEnabled(monitorEnabled).setMonitorProtocol(monitorType).build();
845 ItmUtils.asyncUpdate(LogicalDatastoreType.CONFIGURATION, path, tunnelMonitor, dataBroker,
846 ItmUtils.DEFAULT_CALLBACK);
851 public void configureTunnelMonitorInterval(int interval) {
852 InstanceIdentifier<TunnelMonitorInterval> path = InstanceIdentifier.builder(TunnelMonitorInterval.class).build();
853 Optional<TunnelMonitorInterval> storedTunnelMonitor = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
854 if (!storedTunnelMonitor.isPresent() || storedTunnelMonitor.get().getInterval() != interval) {
855 TunnelMonitorInterval tunnelMonitor = new TunnelMonitorIntervalBuilder().setInterval(interval).build();
856 ItmUtils.asyncUpdate(LogicalDatastoreType.CONFIGURATION, path, tunnelMonitor, dataBroker,
857 ItmUtils.DEFAULT_CALLBACK);
861 public void handleError(String errorMessage, CommandSession session) throws TepException {
862 if(session != null) {
863 session.getConsole().println(errorMessage);
865 throw new TepException(errorMessage);