import ietf-inet-types {
prefix inet;
+ revision-date "2010-09-24";
}
import opendaylight-inventory {
<version>0.2.0-SNAPSHOT</version>
<relativePath>../../commons/config-parent</relativePath>
</parent>
-
+
<modelVersion>4.0.0</modelVersion>
<groupId>org.opendaylight.vpnservice</groupId>
<artifactId>itm-api</artifactId>
<artifactId>interfacemgr-api</artifactId>
<version>${vpnservices.version}</version>
</dependency>
+ <!--
<dependency>
<groupId>org.opendaylight.mdsal.model</groupId>
<artifactId>ietf-inet-types</artifactId>
+ <version>2010.09.24.8-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.mdsal.model</groupId>
<artifactId>ietf-yang-types</artifactId>
</dependency>
+ -->
<dependency>
<groupId>org.opendaylight.mdsal.model</groupId>
<artifactId>ietf-interfaces</artifactId>
--- /dev/null
+module itm-rpc {
+ namespace "urn:opendaylight:params:xml:ns:yang:itm:rpcs";
+ prefix "itmrpcs";
+
+ import ietf-inet-types {
+ prefix inet;
+ revision-date "2010-09-24";
+ }
+
+ import ietf-yang-types {
+ prefix yang;
+ }
+
+ import ietf-interfaces {
+ prefix if; revision-date 2014-05-08;
+ }
+
+ revision "2015-12-17" {
+ description "ODL Specific Itm Manager Rpcs Module";
+ }
+
+ /* RPCs */
+
+ rpc get-tunnel-interface-id {
+ description "used to retrieve tunnel interface id between Dpns";
+ input {
+ leaf source-dpid {
+ type uint64;
+ }
+ leaf destination-dpid {
+ type uint64;
+ }
+ }
+ output {
+ leaf interfaceid {
+ type uint16;
+ }
+ }
+ }
+
+ rpc build-tunnel-from-dpn-to-dcgateway {
+ description "used for building tunnels between a Dpn and DC Gateway";
+ input {
+ leaf dpid {
+ type uint64;
+ }
+ leaf dcgwyid {
+ type inet:ip-address;
+ }
+ }
+ }
+
+ rpc build-tunnel-to-dcgateway {
+ description "used for building tunnels between teps on all Dpns and DC Gateway";
+ input {
+ leaf dcgwyid {
+ type inet:ip-address;
+ }
+ }
+ }
+}
\ No newline at end of file
import ietf-inet-types {
prefix inet;
+ revision-date "2010-09-24";
}
description "This YANG module defines operation part of the model.";
}
import ietf-inet-types {
prefix inet;
+ revision-date "2010-09-24";
}
import config { prefix config; revision-date 2013-04-05; }
<artifactId>interfacemgr-api</artifactId>
<version>${vpnservices.version}</version>
</dependency>
- <dependency>
- <groupId>org.opendaylight.vpnservice</groupId>
- <artifactId>interfacemgr-impl</artifactId>
- <version>${vpnservices.version}</version>
- </dependency>
<dependency>
<groupId>org.opendaylight.vpnservice</groupId>
<artifactId>mdsalutil-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
- <groupId>org.opendaylight.vpnservice</groupId>
- <artifactId>interfacemgr-api</artifactId>
- <version>${vpnservices.version}</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.vpnservice</groupId>
- <artifactId>mdsalutil-api</artifactId>
- <version>${vpnservices.version}</version>
- </dependency>
- <dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.itm.confighelpers;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.itm.impl.ItmUtils;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.tunnels.DPNTEPsInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.tunnels.dpn.teps.info.TunnelEndPoints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeBase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeGre;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeVxlan;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.commons.net.util.SubnetUtils;
+
+import com.google.common.util.concurrent.ListenableFuture;
+
+public class ItmExternalTunnelAddWorker {
+ private static final Logger logger = LoggerFactory.getLogger(ItmExternalTunnelAddWorker.class ) ;
+
+ public static List<ListenableFuture<Void>> buildTunnelsToExternalEndPoint(DataBroker dataBroker,List<DPNTEPsInfo> meshedDpnList, IpAddress extIp) {
+ List<ListenableFuture<Void>> futures = new ArrayList<>();
+ WriteTransaction t = dataBroker.newWriteOnlyTransaction();
+ if( null == meshedDpnList)
+ ItmUtils.getTunnelMeshInfo(dataBroker) ;
+ if( null != meshedDpnList) {
+ for( DPNTEPsInfo teps : meshedDpnList ) {
+ // CHECK -- Assumption -- Only one End Point / Dpn for GRE/Vxlan Tunnels
+ TunnelEndPoints firstEndPt = teps.getTunnelEndPoints().get(0) ;
+ String interfaceName = firstEndPt.getInterfaceName() ;
+ String trunkInterfaceName = ItmUtils.getTrunkInterfaceName(interfaceName, firstEndPt.getIpAddress().getIpv4Address().getValue(), extIp.getIpv4Address().getValue()) ;
+ char[] subnetMaskArray = firstEndPt.getSubnetMask().getValue() ;
+ String subnetMaskStr = String.valueOf(subnetMaskArray) ;
+ SubnetUtils utils = new SubnetUtils(subnetMaskStr);
+ String dcGwyIpStr = String.valueOf(extIp.getValue());
+ IpAddress gwyIpAddress = (utils.getInfo().isInRange(dcGwyIpStr) ) ? null : firstEndPt.getGwIpAddress() ;
+ Class<? extends TunnelTypeBase> tunType = (teps.getTunnelEndPoints().get(0).getTunnelType().equals("GRE") ) ? TunnelTypeGre.class :TunnelTypeVxlan.class ;
+ String ifDescription = (tunType.equals("GRE") ) ? "GRE" : "VxLan" ;
+ logger.debug( " Creating Trunk Interface with parameters trunk I/f Name - {}, parent I/f name - {}, source IP - {}, DC Gateway IP - {} gateway IP - {}",trunkInterfaceName, interfaceName, firstEndPt.getIpAddress(), extIp, gwyIpAddress ) ;
+ Interface iface = ItmUtils.buildTunnelInterface(teps.getDPNID(), trunkInterfaceName, String.format( "%s %s",ifDescription, "Trunk Interface"), true, tunType, firstEndPt.getIpAddress(), extIp, gwyIpAddress) ;
+ logger.debug( " Trunk Interface builder - {} ", iface ) ;
+ InstanceIdentifier<Interface> trunkIdentifier = ItmUtils.buildId(trunkInterfaceName);
+ logger.debug( " Trunk Interface Identifier - {} ", trunkIdentifier ) ;
+ logger.trace( " Writing Trunk Interface to Config DS {}, {} ", trunkIdentifier, iface ) ;
+ //ItmUtils.asyncUpdate(LogicalDatastoreType.CONFIGURATION,trunkIdentifier, iface , dataBroker, ItmUtils.DEFAULT_CALLBACK);
+ t.merge(LogicalDatastoreType.CONFIGURATION, trunkIdentifier, iface, true);
+ }
+ futures.add( t.submit()) ;
+ }
+ return futures ;
+ }
+
+ public static List<ListenableFuture<Void>> buildTunnelsFromDpnToExternalEndPoint(DataBroker dataBroker,BigInteger dpnId,List<DPNTEPsInfo> meshedDpnList, IpAddress extIp) {
+ List<ListenableFuture<Void>> futures = new ArrayList<>();
+ List<DPNTEPsInfo> cfgDpnList = new ArrayList<DPNTEPsInfo>() ;
+ if( null != meshedDpnList) {
+ for( DPNTEPsInfo teps : meshedDpnList ) {
+ if( teps.getDPNID().equals(dpnId)) {
+ cfgDpnList.add(teps) ;
+ }
+ }
+ futures = buildTunnelsToExternalEndPoint( dataBroker, cfgDpnList, extIp) ;
+ }
+ return futures ;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.itm.confighelpers;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.itm.impl.ItmUtils;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.tunnels.DPNTEPsInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.tunnels.dpn.teps.info.TunnelEndPoints;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.util.concurrent.ListenableFuture;
+
+public class ItmExternalTunnelDeleteWorker {
+ private static final Logger logger = LoggerFactory.getLogger(ItmExternalTunnelDeleteWorker.class ) ;
+
+ public static List<ListenableFuture<Void>> deleteTunnels(DataBroker dataBroker, List<DPNTEPsInfo> dpnTepsList,IpAddress extIp ) {
+ logger.trace( " Delete Tunnels towards DC Gateway with Ip {}", extIp ) ;
+ List<ListenableFuture<Void>> futures = new ArrayList<>();
+ WriteTransaction t = dataBroker.newWriteOnlyTransaction();
+
+ if (dpnTepsList == null || dpnTepsList.size() == 0) {
+ logger.debug("no vtep to delete");
+ return null ;
+ }
+ for( DPNTEPsInfo teps : dpnTepsList) {
+ TunnelEndPoints firstEndPt = teps.getTunnelEndPoints().get(0) ;
+ String interfaceName = firstEndPt.getInterfaceName() ;
+ String trunkInterfaceName = ItmUtils.getTrunkInterfaceName(interfaceName, firstEndPt.getIpAddress().getIpv4Address().getValue(), extIp.getIpv4Address().getValue()) ;
+ InstanceIdentifier<Interface> trunkIdentifier = ItmUtils.buildId(trunkInterfaceName);
+ t.delete(LogicalDatastoreType.CONFIGURATION, trunkIdentifier);
+ }
+ futures.add(t.submit()) ;
+ return futures ;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.itm.confighelpers;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Callable;
+
+import com.google.common.util.concurrent.ListenableFuture;
+
+import org.opendaylight.vpnservice.itm.impl.ItmUtils;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.Tunnels;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.TunnelsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.tunnels.DPNTEPsInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.tunnels.dpn.teps.info.TunnelEndPoints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeBase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeGre;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeVxlan;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ItmInternalTunnelAddWorker {
+ private static final Logger logger = LoggerFactory.getLogger(ItmInternalTunnelAddWorker.class) ;
+
+ public static List<ListenableFuture<Void>> build_all_tunnels(DataBroker dataBroker, List<DPNTEPsInfo> cfgdDpnList, List<DPNTEPsInfo> meshedDpnList) {
+ logger.trace( "Building tunnels with DPN List {} " , cfgdDpnList );
+ List<ListenableFuture<Void>> futures = new ArrayList<>();
+ WriteTransaction t = dataBroker.newWriteOnlyTransaction();
+ if( null == cfgdDpnList || cfgdDpnList.isEmpty()) {
+ logger.error(" Build Tunnels was invoked with empty list");
+ return null;
+ }
+
+ for( DPNTEPsInfo dpn : cfgdDpnList) {
+ build_tunnel_from(dpn, meshedDpnList, dataBroker, t, futures);
+ if(null == meshedDpnList) {
+ meshedDpnList = new ArrayList<DPNTEPsInfo>() ;
+ }
+ meshedDpnList.add(dpn) ;
+ // Update the operational datastore -- FIXME -- Error Handling
+ updateOperationalDatastore(dataBroker, dpn, t, futures) ;
+ }
+ futures.add( t.submit()) ;
+ return futures ;
+ }
+
+ private static void updateOperationalDatastore(DataBroker dataBroker, DPNTEPsInfo dpn, WriteTransaction t, List<ListenableFuture<Void>> futures) {
+ logger.debug("Updating CONFIGURATION datastore with DPN {} ", dpn);
+ InstanceIdentifier<Tunnels> tnId = InstanceIdentifier.builder( Tunnels.class).build() ;
+ List<DPNTEPsInfo> dpnList = new ArrayList<DPNTEPsInfo>() ;
+ dpnList.add(dpn) ;
+ Tunnels tnlBuilder = new TunnelsBuilder().setDPNTEPsInfo(dpnList).build() ;
+ t.merge(LogicalDatastoreType.CONFIGURATION, tnId, tnlBuilder, true);
+ }
+
+ private static void build_tunnel_from( DPNTEPsInfo srcDpn,List<DPNTEPsInfo> meshedDpnList, DataBroker dataBroker, WriteTransaction t, List<ListenableFuture<Void>> futures) {
+ logger.trace( "Building tunnels from DPN {} " , srcDpn );
+
+ if( null == meshedDpnList || 0 == meshedDpnList.size()) {
+ logger.debug( "No DPN in the mesh ");
+ return ;
+ }
+ for( DPNTEPsInfo dstDpn: meshedDpnList) {
+ if ( ! srcDpn.equals(dstDpn) )
+ wireUpWithinTransportZone(srcDpn, dstDpn, dataBroker, t, futures) ;
+ }
+
+ }
+
+ private static void wireUpWithinTransportZone( DPNTEPsInfo srcDpn, DPNTEPsInfo dstDpn, DataBroker dataBroker, WriteTransaction t, List<ListenableFuture<Void>> futures) {
+ logger.trace( "Wiring up within Transport Zone for Dpns {}, {} " , srcDpn, dstDpn );
+ List<TunnelEndPoints> srcEndPts = srcDpn.getTunnelEndPoints();
+ List<TunnelEndPoints> dstEndPts = dstDpn.getTunnelEndPoints();
+
+ for( TunnelEndPoints srcte : srcEndPts) {
+ for( TunnelEndPoints dstte : dstEndPts ) {
+ // Compare the Transport zones
+ if (!srcDpn.getDPNID().equals(dstDpn.getDPNID())) {
+ if( (srcte.getTransportZone().equals(dstte.getTransportZone()))) {
+ // wire them up
+ wireUpBidirectionalTunnel( srcte, dstte, srcDpn.getDPNID(), dstDpn.getDPNID(), dataBroker, t, futures );
+ // CHECK THIS -- Assumption -- One end point per Dpn per transport zone
+ break ;
+ }
+ }
+ }
+ }
+ }
+
+ private static void wireUpBidirectionalTunnel( TunnelEndPoints srcte, TunnelEndPoints dstte, BigInteger srcDpnId, BigInteger dstDpnId,
+ DataBroker dataBroker, WriteTransaction t, List<ListenableFuture<Void>> futures) {
+ // Setup the flow for LLDP monitoring -- PUNT TO CONTROLLER
+ // setUpOrRemoveTerminatingServiceTable(srcDpnId, true);
+ // setUpOrRemoveTerminatingServiceTable(dstDpnId, true);
+
+ // Create the forward direction tunnel
+ if(!wireUp( srcte, dstte, srcDpnId, dstDpnId, dataBroker, t, futures ))
+ logger.error("Could not build tunnel between end points {}, {} " , srcte, dstte );
+
+ // CHECK IF FORWARD IS NOT BUILT , REVERSE CAN BE BUILT
+ // Create the tunnel for the reverse direction
+ if(! wireUp( dstte, srcte, dstDpnId, srcDpnId, dataBroker, t, futures ))
+ logger.error("Could not build tunnel between end points {}, {} " , dstte, srcte);
+ }
+
+ private static boolean wireUp( TunnelEndPoints srcte, TunnelEndPoints dstte, BigInteger srcDpnId, BigInteger dstDpnId ,
+ DataBroker dataBroker, WriteTransaction t, List<ListenableFuture<Void>> futures) {
+ // Wire Up logic
+ logger.trace( "Wiring between source tunnel end points {}, destination tunnel end points {} " , srcte, dstte );
+ String interfaceName = srcte.getInterfaceName() ;
+ Class<? extends TunnelTypeBase> tunType = (srcte.getTunnelType().equals("GRE") ) ? TunnelTypeGre.class :TunnelTypeVxlan.class ;
+ String ifDescription = (srcte.getTunnelType().equals("GRE") ) ? "GRE" : "VxLan" ;
+ // Form the trunk Interface Name
+ String trunkInterfaceName = ItmUtils.getTrunkInterfaceName(interfaceName,srcte.getIpAddress().getIpv4Address().getValue(), dstte.getIpAddress().getIpv4Address().getValue()) ;
+ IpAddress gwyIpAddress = ( srcte.getSubnetMask().equals(dstte.getSubnetMask()) ) ? null : srcte.getGwIpAddress() ;
+ logger.debug( " Creating Trunk Interface with parameters trunk I/f Name - {}, parent I/f name - {}, source IP - {}, destination IP - {} gateway IP - {}",trunkInterfaceName, interfaceName, srcte.getIpAddress(), dstte.getIpAddress(), gwyIpAddress ) ;
+ Interface iface = ItmUtils.buildTunnelInterface(srcDpnId, trunkInterfaceName, String.format( "%s %s",ifDescription, "Trunk Interface"), true, tunType, srcte.getIpAddress(), dstte.getIpAddress(), gwyIpAddress) ;
+ logger.debug( " Trunk Interface builder - {} ", iface ) ;
+ InstanceIdentifier<Interface> trunkIdentifier = ItmUtils.buildId(trunkInterfaceName);
+ logger.debug( " Trunk Interface Identifier - {} ", trunkIdentifier ) ;
+ logger.trace( " Writing Trunk Interface to Config DS {}, {} ", trunkIdentifier, iface ) ;
+ t.merge(LogicalDatastoreType.CONFIGURATION, trunkIdentifier, iface, true);
+ return true;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.itm.confighelpers;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Callable;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.itm.impl.ItmUtils;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.Tunnels;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.tunnels.DPNTEPsInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.tunnels.dpn.teps.info.TunnelEndPoints;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.ListenableFuture;
+
+public class ItmInternalTunnelDeleteWorker {
+ private static final Logger logger = LoggerFactory.getLogger(ItmInternalTunnelDeleteWorker.class) ;
+
+ public static List<ListenableFuture<Void>> deleteTunnels(DataBroker dataBroker, List<DPNTEPsInfo> dpnTepsList, List<DPNTEPsInfo> meshedDpnList)
+ {
+ List<ListenableFuture<Void>> futures = new ArrayList<>();
+ WriteTransaction t = dataBroker.newWriteOnlyTransaction();
+ try {
+ if (dpnTepsList == null || dpnTepsList.size() == 0) {
+ logger.debug("no vtep to delete");
+ return null ;
+ }
+
+ if (meshedDpnList == null || meshedDpnList.size() == 0) {
+ logger.debug("No Meshed Vteps");
+ return null ;
+ }
+ for (DPNTEPsInfo srcDpn : dpnTepsList) {
+ logger.trace("Processing srcDpn " + srcDpn);
+ for (TunnelEndPoints srcTep : srcDpn.getTunnelEndPoints()) {
+ logger.trace("Processing srcTep " + srcTep);
+ String srcTZone = srcTep.getTransportZone();
+
+ // run through all other DPNS other than srcDpn
+ for (DPNTEPsInfo dstDpn : meshedDpnList) {
+ if (!(srcDpn.getDPNID().equals(dstDpn.getDPNID()))) {
+ for (TunnelEndPoints dstTep : dstDpn.getTunnelEndPoints()) {
+ logger.trace("Processing dstTep " + dstTep);
+ if (dstTep.getTransportZone().equals(srcTZone)) {
+ // remove all trunk interfaces
+ logger.trace("Invoking removeTrunkInterface between source TEP {} , Destination TEP {} " ,srcTep , dstTep);
+ removeTrunkInterface(dataBroker, srcTep, dstTep, srcDpn.getDPNID(), dstDpn.getDPNID(), t, futures);
+ }
+ }
+ }
+ }
+
+ // removing vtep / dpn from Tunnels OpDs.
+ InstanceIdentifier<TunnelEndPoints> tepPath =
+ InstanceIdentifier.builder(Tunnels.class).child(DPNTEPsInfo.class, srcDpn.getKey())
+ .child(TunnelEndPoints.class, srcTep.getKey()).build();
+
+ logger.trace("Tep Removal from DPNTEPSINFO CONFIG DS " + srcTep);
+ t.delete(LogicalDatastoreType.CONFIGURATION, tepPath);
+ InstanceIdentifier<DPNTEPsInfo> dpnPath =
+ InstanceIdentifier.builder(Tunnels.class).child(DPNTEPsInfo.class, srcDpn.getKey())
+ .build();
+ Optional<DPNTEPsInfo> dpnOptional =
+ ItmUtils.read(LogicalDatastoreType.CONFIGURATION, dpnPath, dataBroker);
+ if (dpnOptional.isPresent()) {
+ DPNTEPsInfo dpnRead = dpnOptional.get();
+ // remove dpn if no vteps exist on dpn
+ if (dpnRead.getTunnelEndPoints() == null || dpnRead.getTunnelEndPoints().size() == 0) {
+ logger.debug( "Removing Terminating Service Table Flow ") ;
+ // setUpOrRemoveTerminatingServiceTable(dpnRead.getDPNID(), false);
+ logger.trace("DPN Removal from DPNTEPSINFO CONFIG DS " + dpnRead);
+ t.delete(LogicalDatastoreType.CONFIGURATION, dpnPath);
+ InstanceIdentifier<Tunnels> tnlContainerPath =
+ InstanceIdentifier.builder(Tunnels.class).build();
+ Optional<Tunnels> containerOptional =
+ ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
+ tnlContainerPath, dataBroker);
+ // remove container if no DPNs are present
+ if (containerOptional.isPresent()) {
+ Tunnels tnls = containerOptional.get();
+ if (tnls.getDPNTEPsInfo() == null || tnls.getDPNTEPsInfo().isEmpty()) {
+ logger.trace("Container Removal from DPNTEPSINFO CONFIG DS");
+ t.delete(LogicalDatastoreType.CONFIGURATION, tnlContainerPath);
+ }
+ }
+ }
+ }
+ }
+ }
+ futures.add( t.submit() );
+ } catch (Exception e1) {
+ logger.error("exception while deleting tep", e1);
+ }
+ return futures ;
+ }
+
+ private static void removeTrunkInterface(DataBroker dataBroker, TunnelEndPoints srcTep, TunnelEndPoints dstTep, BigInteger srcDpnId, BigInteger dstDpnId,
+ WriteTransaction t, List<ListenableFuture<Void>> futures) {
+ String trunkfwdIfName =
+ ItmUtils.getTrunkInterfaceName(srcTep.getInterfaceName(), srcTep.getIpAddress()
+ .getIpv4Address().getValue(), dstTep.getIpAddress().getIpv4Address()
+ .getValue());
+ logger.trace("Removing forward Trunk Interface " + trunkfwdIfName);
+ InstanceIdentifier<Interface> trunkIdentifier = ItmUtils.buildId(trunkfwdIfName);
+ logger.debug( " Removing Trunk Interface Name - {} , Id - {} from Config DS {}, {} ", trunkfwdIfName, trunkIdentifier ) ;
+ t.delete(LogicalDatastoreType.CONFIGURATION, trunkIdentifier);
+ String trunkRevIfName =
+ ItmUtils.getTrunkInterfaceName(dstTep.getInterfaceName(), dstTep.getIpAddress()
+ .getIpv4Address().getValue(), srcTep.getIpAddress().getIpv4Address()
+ .getValue());
+ logger.trace("Removing Reverse Trunk Interface " + trunkRevIfName);
+ trunkIdentifier = ItmUtils.buildId(trunkfwdIfName);
+ logger.debug( " Removing Trunk Interface Name - {} , Id - {} from Config DS {}, {} ", trunkfwdIfName, trunkIdentifier ) ;
+ t.delete(LogicalDatastoreType.CONFIGURATION, trunkIdentifier);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.itm.confighelpers;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Callable;
+
+import com.google.common.util.concurrent.ListenableFuture;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.vpnservice.itm.impl.ItmUtils;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.tunnels.DPNTEPsInfo;
+import org.slf4j.LoggerFactory;
+import org.slf4j.Logger;
+
+public class ItmTepAddWorker implements Callable<List<ListenableFuture<Void>>> {
+ private static final Logger logger = LoggerFactory.getLogger(ItmTepAddWorker.class ) ;
+ private DataBroker dataBroker;
+ private List<DPNTEPsInfo> meshedDpnList;
+ private List<DPNTEPsInfo> cfgdDpnList ;
+
+ public ItmTepAddWorker( List<DPNTEPsInfo> cfgdDpnList, DataBroker broker) {
+ this.cfgdDpnList = cfgdDpnList ;
+ this.dataBroker = broker ;
+ logger.trace("ItmTepAddWorker initialized with DpnList {}",cfgdDpnList );
+ }
+
+ @Override
+ public List<ListenableFuture<Void>> call() throws Exception {
+ List<ListenableFuture<Void>> futures = new ArrayList<>() ;
+ this.meshedDpnList = ItmUtils.getTunnelMeshInfo(dataBroker) ;
+ logger.debug("Invoking Internal Tunnel build method with Configured DpnList {} ; Meshed DpnList {} ",cfgdDpnList, meshedDpnList );
+ futures.addAll( ItmInternalTunnelAddWorker.build_all_tunnels(dataBroker, cfgdDpnList, meshedDpnList) ) ;
+ // IF EXTERNAL TUNNELS NEEDS TO BE BUILT, DO IT HERE. IT COULD BE TO DC GATEWAY OR TOR SWITCH
+ //futures.addAll(ItmExternalTunnelAddWorker.buildTunnelsToExternalEndPoint(dataBroker,meshedDpnList, extIp) ;
+ return futures ;
+ }
+
+ @Override
+ public String toString() {
+ return "ItmTepAddWorker { " +
+ "Configured Dpn List : " + cfgdDpnList +
+ " Meshed Dpn List : " + meshedDpnList + " }" ;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.itm.confighelpers;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Callable;
+
+import com.google.common.util.concurrent.ListenableFuture;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.vpnservice.itm.impl.ItmUtils;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.tunnels.DPNTEPsInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ItmTepRemoveWorker implements Callable<List<ListenableFuture<Void>>> {
+ private static final Logger logger = LoggerFactory.getLogger(ItmTepRemoveWorker.class ) ;
+ private DataBroker dataBroker;
+ private List<DPNTEPsInfo> delDpnList ;
+ private List<DPNTEPsInfo> meshedDpnList ;
+
+ public ItmTepRemoveWorker( List<DPNTEPsInfo> delDpnList, DataBroker broker) {
+ this.delDpnList = delDpnList ;
+ this.dataBroker = broker ;
+ logger.trace("ItmTepRemoveWorker initialized with DpnList {}",delDpnList );
+ }
+
+ @Override
+ public List<ListenableFuture<Void>> call() throws Exception {
+ List<ListenableFuture<Void>> futures = new ArrayList<>() ;
+ this.meshedDpnList = ItmUtils.getTunnelMeshInfo(dataBroker) ;
+ futures.addAll( ItmInternalTunnelDeleteWorker.deleteTunnels(dataBroker, delDpnList, meshedDpnList));
+ logger.debug("Invoking Internal Tunnel delete method with DpnList to be deleted {} ; Meshed DpnList {} ",delDpnList, meshedDpnList );
+ // IF EXTERNAL TUNNELS NEEDS TO BE DELETED, DO IT HERE, IT COULD BE TO DC GATEWAY OR TOR SWITCH
+ return futures ;
+ }
+
+ @Override
+ public String toString() {
+ return "ItmTepRemoveWorker { " +
+ "Delete Dpn List : " + delDpnList + " }" ;
+ }
+}
import java.util.List;
import java.util.concurrent.Future;
+import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
import org.apache.commons.net.util.SubnetUtils;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
import org.opendaylight.controller.md.sal.binding.api.NotificationService;
-
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.Tunnels;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.TunnelsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeBase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeGre;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeVxlan ;
import org.opendaylight.vpnservice.itm.globals.ITMConstants;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.tunnels.DPNTEPsInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.tunnels.dpn.teps.info.TunnelEndPoints;
+
+import com.google.common.base.Optional;
public class ITMManager implements AutoCloseable {
private IMdsalApiManager mdsalManager;
private NotificationPublishService notificationPublishService;
+ List<DPNTEPsInfo> meshedDpnList;
+
@Override
public void close() throws Exception {
LOG.info("ITMManager Closed");
import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
import org.opendaylight.vpnservice.itm.api.IITMProvider;
-
+import org.opendaylight.vpnservice.itm.listeners.TransportZoneListener;
+import org.opendaylight.vpnservice.itm.rpc.ItmManagerRpcService;
import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.GetTunnelIdInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.GetTunnelIdOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.ItmStateService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.TunnelsState;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.rev150701.TransportZones;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.rev150701.transport.zones.transport.zone.*;;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private IMdsalApiManager mdsalManager;
private DataBroker dataBroker;
private NotificationPublishService notificationPublishService;
+ private ItmManagerRpcService itmRpcService ;
private NotificationService notificationService;
-
+ private TransportZoneListener tzChangeListener;
+
@Override
public void onSessionInitiated(ProviderContext session) {
LOG.info("ItmProvider Session Initiated");
try {
dataBroker = session.getSALService(DataBroker.class);
-
+
itmManager = new ITMManager(dataBroker);
-
+ tzChangeListener = new TransportZoneListener(dataBroker) ;
+ itmRpcService = new ItmManagerRpcService(dataBroker);
+
itmManager.setMdsalManager(mdsalManager);
itmManager.setNotificationPublishService(notificationPublishService);
itmManager.setMdsalManager(mdsalManager);
-
+ tzChangeListener.setItmManager(itmManager);
+ tzChangeListener.registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
} catch (Exception e) {
LOG.error("Error initializing services", e);
}
if (itmManager != null) {
itmManager.close();
}
-
+ if (tzChangeListener != null) {
+ tzChangeListener.close();
+ }
+
LOG.info("ItmProvider Closed");
}
- @Override
- public Future<RpcResult<GetTunnelIdOutput>> getTunnelId(
- GetTunnelIdInput input) {
- // TODO Auto-generated method stub
- return null;
- }
+ @Override
+ public Future<RpcResult<GetTunnelIdOutput>> getTunnelId(
+ GetTunnelIdInput input) {
+ // TODO Auto-generated method stub
+ return null;
+ }
}
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.itm.impl;
+
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.net.util.SubnetUtils;
+import org.apache.commons.net.util.SubnetUtils.SubnetInfo;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.*;
+import org.opendaylight.vpnservice.itm.globals.ITMConstants;
+import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.Tunnels;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.TunnelsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.tunnels.DPNTEPsInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.tunnels.DPNTEPsInfoBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.tunnels.DPNTEPsInfoKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.tunnels.dpn.teps.info.TunnelEndPoints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.tunnels.dpn.teps.info.TunnelEndPointsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.tunnels.dpn.teps.info.TunnelEndPointsKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.tunnels_state.StateTunnelListKey;
+//import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice._interface.service.rev150602._interface.service.info.ServiceInfo;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.net.InetAddresses;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+
+public class ItmUtils {
+
+ public static final String DUMMY_IP_ADDRESS = "0.0.0.0";
+ public static final String TUNNEL_TYPE_VXLAN = "VXLAN";
+ public static final String TUNNEL_TYPE_GRE = "GRE";
+
+ private static final Logger LOG = LoggerFactory.getLogger(ItmUtils.class);
+
+ public static final FutureCallback<Void> DEFAULT_CALLBACK = new FutureCallback<Void>() {
+ public void onSuccess(Void result) {
+ LOG.debug("Success in Datastore write operation");
+ }
+
+ public void onFailure(Throwable error) {
+ LOG.error("Error in Datastore write operation", error);
+ }
+ };
+
+ public static <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType,
+ InstanceIdentifier<T> path, DataBroker broker) {
+
+ ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
+
+ Optional<T> result = Optional.absent();
+ try {
+ result = tx.read(datastoreType, path).get();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ return result;
+ }
+
+ public static <T extends DataObject> void asyncWrite(LogicalDatastoreType datastoreType,
+ InstanceIdentifier<T> path, T data, DataBroker broker, FutureCallback<Void> callback) {
+ WriteTransaction tx = broker.newWriteOnlyTransaction();
+ tx.put(datastoreType, path, data, true);
+ Futures.addCallback(tx.submit(), callback);
+ }
+
+ public static <T extends DataObject> void asyncUpdate(LogicalDatastoreType datastoreType,
+ InstanceIdentifier<T> path, T data, DataBroker broker, FutureCallback<Void> callback) {
+ WriteTransaction tx = broker.newWriteOnlyTransaction();
+ tx.merge(datastoreType, path, data, true);
+ Futures.addCallback(tx.submit(), callback);
+ }
+
+ public static <T extends DataObject> void asyncDelete(LogicalDatastoreType datastoreType,
+ InstanceIdentifier<T> path, DataBroker broker, FutureCallback<Void> callback) {
+ WriteTransaction tx = broker.newWriteOnlyTransaction();
+ tx.delete(datastoreType, path);
+ Futures.addCallback(tx.submit(), callback);
+ }
+
+ public static String getInterfaceName(final BigInteger datapathid, final String portName, final Integer vlanId) {
+ return String.format("%s:%s:%s", datapathid, portName, vlanId);
+ }
+
+ public static BigInteger getDpnIdFromInterfaceName(String interfaceName) {
+ String[] dpnStr = interfaceName.split(":");
+ BigInteger dpnId = new BigInteger(dpnStr[0]);
+ return dpnId;
+ }
+
+ public static String getTrunkInterfaceName(String parentInterfaceName, String localHostName, String remoteHostName) {
+ String trunkInterfaceName = String.format("%s:%s:%s", parentInterfaceName, localHostName, remoteHostName);
+ return trunkInterfaceName;
+ }
+
+ public static InetAddress getInetAddressFromIpAddress(IpAddress ip) {
+ return InetAddresses.forString(ip.getIpv4Address().getValue());
+ }
+
+ public static InstanceIdentifier<DPNTEPsInfo> getDPNTEPInstance(BigInteger dpIdKey) {
+ InstanceIdentifier.InstanceIdentifierBuilder<DPNTEPsInfo> dpnTepInfoBuilder =
+ InstanceIdentifier.builder(Tunnels.class).child(DPNTEPsInfo.class, new DPNTEPsInfoKey(dpIdKey));
+ InstanceIdentifier<DPNTEPsInfo> dpnInfo = dpnTepInfoBuilder.build();
+ return dpnInfo;
+ }
+
+ public static DPNTEPsInfo createDPNTepInfo(BigInteger dpId, List<TunnelEndPoints> endpoints) {
+
+ return new DPNTEPsInfoBuilder().setKey(new DPNTEPsInfoKey(dpId)).setTunnelEndPoints(endpoints).build();
+ }
+
+ public static TunnelEndPoints createTunnelEndPoints(BigInteger dpnId, IpAddress ipAddress, String portName, int vlanId,
+ IpPrefix prefix, IpAddress gwAddress, String zoneName, String tunnel_type) {
+ // when Interface Mgr provides support to take in Dpn Id
+ return new TunnelEndPointsBuilder().setKey(new TunnelEndPointsKey(ipAddress, portName, vlanId))
+ .setSubnetMask(prefix).setGwIpAddress(gwAddress).setTransportZone(zoneName)
+ .setInterfaceName(ItmUtils.getInterfaceName(dpnId, portName, vlanId)).setTunnelType(tunnel_type).build();
+ }
+
+ public static Tunnels createTunnel(List<DPNTEPsInfo> dpnTepInfo) {
+ return new TunnelsBuilder().setDPNTEPsInfo(dpnTepInfo).build();
+ }
+
+ public static InstanceIdentifier<Interface> buildId(String interfaceName) {
+ InstanceIdentifierBuilder<Interface> idBuilder =
+ InstanceIdentifier.builder(Interfaces.class).child(Interface.class, new InterfaceKey(interfaceName));
+ InstanceIdentifier<Interface> id = idBuilder.build();
+ return id;
+ }
+
+ public static Interface buildTunnelInterface(BigInteger dpn, String ifName, String desc, boolean enabled, Class<? extends TunnelTypeBase> tunType,
+ IpAddress localIp, IpAddress remoteIp, IpAddress gatewayIp) {
+ InterfaceBuilder builder = new InterfaceBuilder().setKey(new InterfaceKey(ifName)).setName(ifName)
+ .setDescription(desc).setEnabled(enabled).setType(Tunnel.class);
+ ParentRefs parentRefs = new ParentRefsBuilder().setDatapathNodeIdentifier(dpn).build();
+ builder.addAugmentation(ParentRefs.class, parentRefs);
+ IfTunnel tunnel = new IfTunnelBuilder().setTunnelDestination(remoteIp).setTunnelGateway(gatewayIp).setTunnelSource(localIp)
+ .setTunnelInterfaceType( tunType).build();
+ builder.addAugmentation(IfTunnel.class, tunnel);
+ return builder.build();
+ }
+
+ public static List<DPNTEPsInfo> getTunnelMeshInfo(DataBroker dataBroker) {
+ List<DPNTEPsInfo> dpnTEPs= null ;
+
+ // Read the EndPoint Info from the operational database
+ InstanceIdentifierBuilder<Tunnels> tnlBuilder = InstanceIdentifier.builder( Tunnels.class) ;
+ InstanceIdentifier<Tunnels> tnls = tnlBuilder.build() ;
+ Optional<Tunnels> tunnels = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, tnls, dataBroker);
+ if( tunnels.isPresent()) {
+ Tunnels tn= tunnels.get() ;
+ dpnTEPs = tn.getDPNTEPsInfo() ;
+ LOG.debug( "Read from CONFIGURATION datastore - No. of Dpns " , dpnTEPs.size() );
+ }else
+ LOG.debug( "No Dpn information in CONFIGURATION datastore " );
+ return dpnTEPs ;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.vpnservice.itm.listeners;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.ListenableFuture;
+
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.tunnels.DPNTEPsInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.tunnels.dpn.teps.info.TunnelEndPoints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.rev150701.TransportZones;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.rev150701.TransportZonesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.rev150701.transport.zones.TransportZone;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.rev150701.transport.zones.transport.zone.Subnets;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.rev150701.transport.zones.transport.zone.subnets.Vteps;
+import org.opendaylight.vpnservice.datastoreutils.AsyncDataTreeChangeListenerBase;
+import org.opendaylight.vpnservice.datastoreutils.DataStoreJobCoordinator;
+import org.opendaylight.vpnservice.itm.impl.ITMManager;
+import org.opendaylight.vpnservice.itm.impl.ItmUtils;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.vpnservice.itm.confighelpers.ItmTepAddWorker ;
+import org.opendaylight.vpnservice.itm.confighelpers.ItmTepRemoveWorker;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This class listens for interface creation/removal/update in Configuration DS.
+ * This is used to handle interfaces for base of-ports.
+ */
+public class TransportZoneListener extends AsyncDataTreeChangeListenerBase<TransportZone, TransportZoneListener> implements AutoCloseable{
+ private static final Logger LOG = LoggerFactory.getLogger(TransportZoneListener.class);
+ private DataBroker dataBroker;
+ private ITMManager itmManager;
+
+ public TransportZoneListener(final DataBroker dataBroker) {
+ super(TransportZone.class, TransportZoneListener.class);
+ this.dataBroker = dataBroker;
+ initializeTZNode(dataBroker);
+ }
+
+ public void setItmManager(ITMManager itmManager) {
+ this.itmManager = itmManager;
+ }
+
+ private void initializeTZNode(DataBroker db) {
+ ReadWriteTransaction transaction = db.newReadWriteTransaction();
+ InstanceIdentifier<TransportZones> path = InstanceIdentifier.create(TransportZones.class);
+ CheckedFuture<Optional<TransportZones>, ReadFailedException> tzones =
+ transaction.read(LogicalDatastoreType.CONFIGURATION,path);
+ try {
+ if (!tzones.get().isPresent()) {
+ TransportZonesBuilder tzb = new TransportZonesBuilder();
+ transaction.put(LogicalDatastoreType.CONFIGURATION,path,tzb.build());
+ transaction.submit();
+ } else {
+ transaction.cancel();
+ }
+ } catch (Exception e) {
+ LOG.error("Error initializing TransportZones {}",e);
+ }
+ }
+
+ @Override
+ public void close() throws Exception {
+ LOG.info("tzChangeListener Closed");
+ }
+ @Override
+ protected InstanceIdentifier<TransportZone> getWildCardPath() {
+ return InstanceIdentifier.create(TransportZones.class).child(TransportZone.class);
+ }
+
+ @Override
+ protected TransportZoneListener getDataTreeChangeListener() {
+ return TransportZoneListener.this;
+ }
+
+ @Override
+ protected void remove(InstanceIdentifier<TransportZone> key, TransportZone tzOld) {
+ LOG.debug("Received Transport Zone Remove Event: {}, {}", key, tzOld);
+ List<DPNTEPsInfo> opDpnList = createDPNTepInfo(tzOld);
+ LOG.trace("Delete: Invoking deleteTunnels in ItmManager with DpnList {}", opDpnList);
+ if(opDpnList.size()>0) {
+ LOG.trace("Delete: Invoking ItmManager");
+ // itmManager.deleteTunnels(opDpnList);
+ DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
+ ItmTepRemoveWorker removeWorker = new ItmTepRemoveWorker(opDpnList, dataBroker);
+ coordinator.enqueueJob(tzOld.getZoneName(), removeWorker);
+ }
+ }
+
+ @Override
+ protected void update(InstanceIdentifier<TransportZone> key, TransportZone tzOld, TransportZone tzNew) {
+ LOG.debug("Received Transport Zone Update Event: {}, {}, {}", key, tzOld, tzNew);
+ if( !(tzOld.equals(tzNew))) {
+ add(key, tzNew);
+ }
+ }
+
+ @Override
+ protected void add(InstanceIdentifier<TransportZone> key, TransportZone tzNew) {
+ LOG.debug("Received Transport Zone Add Event: {}, {}", key, tzNew);
+ List<DPNTEPsInfo> opDpnList = createDPNTepInfo(tzNew);
+ LOG.trace("Add: Operational dpnTepInfo - Before invoking ItmManager {}", opDpnList);
+ if(opDpnList.size()>0) {
+ LOG.trace("Add: Invoking ItmManager with DPN List {} " , opDpnList);
+ //itmManager.build_all_tunnels(opDpnList);
+ DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
+ ItmTepAddWorker addWorker = new ItmTepAddWorker(opDpnList,dataBroker);
+ coordinator.enqueueJob(tzNew.getZoneName(), addWorker);
+ }
+ }
+
+ private List<DPNTEPsInfo> createDPNTepInfo(TransportZone transportZone){
+
+ Map<BigInteger, List<TunnelEndPoints>> mapDPNToTunnelEndpt = new ConcurrentHashMap<>();
+ List<DPNTEPsInfo> dpnTepInfo = new ArrayList<DPNTEPsInfo>();
+ // List<TransportZone> transportZoneList = transportZones.getTransportZone();
+ // for(TransportZone transportZone : transportZoneList) {
+ String zone_name = transportZone.getZoneName();
+ String tunnel_type = transportZone.getTunnelType();
+ LOG.trace("Transport Zone_name: {}", zone_name);
+ List<Subnets> subnetsList = transportZone.getSubnets();
+ if(subnetsList!=null){
+ for (Subnets subnet : subnetsList) {
+ IpPrefix ipPrefix = subnet.getPrefix();
+ IpAddress gatewayIP = subnet.getGatewayIp();
+ int vlanID = subnet.getVlanId();
+ LOG.trace("IpPrefix: {}, gatewayIP: {}, vlanID: {} ", ipPrefix, gatewayIP, vlanID);
+ List<Vteps> vtepsList = subnet.getVteps();
+ for (Vteps vteps : vtepsList) {
+ BigInteger dpnID = vteps.getDpnId();
+ String port = vteps.getPortname();
+ IpAddress ipAddress = vteps.getIpAddress();
+ LOG.trace("DpnID: {}, port: {}, ipAddress: {}", dpnID, port, ipAddress);
+ TunnelEndPoints tunnelEndPoints = ItmUtils.createTunnelEndPoints(dpnID, ipAddress, port, vlanID, ipPrefix, gatewayIP, zone_name, tunnel_type);
+ List<TunnelEndPoints> tunnelEndPointsList = mapDPNToTunnelEndpt.get(dpnID);
+ if (tunnelEndPointsList != null) {
+ LOG.trace("Existing DPN info list in the Map: {} ", dpnID);
+ tunnelEndPointsList.add(tunnelEndPoints);
+ } else {
+ LOG.trace("Adding new DPN info list to the Map: {} ", dpnID);
+ tunnelEndPointsList = new ArrayList<TunnelEndPoints>();
+ tunnelEndPointsList.add(tunnelEndPoints);
+ mapDPNToTunnelEndpt.put(dpnID, tunnelEndPointsList);
+ }
+ }
+ }
+ }
+ //}
+ if(mapDPNToTunnelEndpt.size()>0){
+ Set<BigInteger> keys = mapDPNToTunnelEndpt.keySet();
+ LOG.trace("List of dpns in the Map: {} ", keys);
+ for(BigInteger key: keys){
+ DPNTEPsInfo newDpnTepsInfo = ItmUtils.createDPNTepInfo(key, mapDPNToTunnelEndpt.get(key));
+ dpnTepInfo.add(newDpnTepsInfo);
+ }
+ }
+ return dpnTepInfo;
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.itm.rpc;
+
+import java.math.BigInteger;
+import java.util.List;
+import java.util.concurrent.Future;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.vpnservice.itm.confighelpers.ItmExternalTunnelAddWorker;
+import org.opendaylight.vpnservice.itm.impl.ItmUtils;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.tunnels.DPNTEPsInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.rpcs.rev151217.BuildTunnelFromDpnToDcgatewayInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.rpcs.rev151217.BuildTunnelToDcgatewayInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.rpcs.rev151217.GetTunnelInterfaceIdInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.rpcs.rev151217.GetTunnelInterfaceIdOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.rpcs.rev151217.GetTunnelInterfaceIdOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.rpcs.rev151217.ItmRpcService;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey;
+
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.SettableFuture;
+
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+
+import com.google.common.base.Optional;
+
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+
+public class ItmManagerRpcService implements ItmRpcService {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ItmRpcService.class);
+ DataBroker dataBroker;
+ public ItmManagerRpcService(DataBroker dataBroker) {
+ this.dataBroker = dataBroker;
+ }
+
+ @Override
+ public Future<RpcResult<java.lang.Void>> buildTunnelFromDpnToDcgateway(BuildTunnelFromDpnToDcgatewayInput input) {
+ //Ignore the Futures for now
+ final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
+ ItmExternalTunnelAddWorker.buildTunnelsFromDpnToExternalEndPoint(dataBroker, input.getDpid(), null, input.getDcgwyid());
+ result.set(RpcResultBuilder.<Void>success().build());
+ return result ;
+ }
+
+ @Override
+ public Future<RpcResult<GetTunnelInterfaceIdOutput>> getTunnelInterfaceId(GetTunnelInterfaceIdInput input) {
+ final SettableFuture<RpcResult<GetTunnelInterfaceIdOutput>> result = SettableFuture.create() ;
+ RpcResultBuilder<GetTunnelInterfaceIdOutput> resultBld = null;
+ BigInteger sourceDpn = input.getSourceDpid() ;
+ BigInteger destinationDpn = input.getDestinationDpid() ;
+ String parentName = null;
+ IpAddress srcIp = null ;
+ IpAddress destIp = null ;
+ List<DPNTEPsInfo> meshDpnList = ItmUtils.getTunnelMeshInfo(dataBroker);
+ for ( DPNTEPsInfo dpn : meshDpnList) {
+ if( (dpn.getDPNID()).equals(sourceDpn) ){
+ parentName = dpn.getTunnelEndPoints().get(0).getInterfaceName();
+ srcIp = dpn.getTunnelEndPoints().get(0).getIpAddress() ;
+ }else if( (dpn.getDPNID()).equals(destinationDpn)) {
+ destIp = dpn.getTunnelEndPoints().get(0).getIpAddress() ;
+ }
+ }
+ if( srcIp != null && destIp != null )
+ {
+ String trunkInterfaceName = ItmUtils.getTrunkInterfaceName(parentName, srcIp.getIpv4Address().getValue(), destIp.getIpv4Address().getValue()) ;
+ InstanceIdentifierBuilder<Interface> idBuilder = InstanceIdentifier.builder(InterfacesState.class)
+ .child(Interface.class, new InterfaceKey(trunkInterfaceName));
+ InstanceIdentifier<Interface> id = idBuilder.build();
+ Optional<Interface> stateIf = ItmUtils.read(LogicalDatastoreType.OPERATIONAL, id, dataBroker);
+ if(stateIf.isPresent()){
+ GetTunnelInterfaceIdOutputBuilder output = new GetTunnelInterfaceIdOutputBuilder() ;
+ output.setInterfaceid(stateIf.get().getIfIndex()) ;
+ resultBld.withResult(output.build()) ;
+ result.set(resultBld.build()) ;
+ }else {
+ result.set(RpcResultBuilder.<GetTunnelInterfaceIdOutput>failed().withError(RpcError.ErrorType.APPLICATION, "Interface Not found ").build()) ;
+ }
+ }else {
+ result.set(RpcResultBuilder.<GetTunnelInterfaceIdOutput>failed().withError(RpcError.ErrorType.APPLICATION, "Source or Destination Dpn Id not found ").build()) ;
+ }
+ return result ;
+ }
+
+ @Override
+ public Future<RpcResult<java.lang.Void>> buildTunnelToDcgateway(BuildTunnelToDcgatewayInput input) {
+ //Ignore the Futures for now
+ final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
+ ItmExternalTunnelAddWorker.buildTunnelsToExternalEndPoint(dataBroker, null, input.getDcgwyid()) ;
+ result.set(RpcResultBuilder.<Void>success().build());
+ return result ;
+ }
+}
import ietf-inet-types {
prefix inet;
+ revision-date "2010-09-24";
//RFC6991
}