[ONOS-6551] Tunnel implementation for L3VPN service.

Change-Id: I3171a83305cb7391d80fda94ddf567629a10675e
diff --git a/apps/l3vpn/BUCK b/apps/l3vpn/BUCK
index 1a59467..1ac39c1 100644
--- a/apps/l3vpn/BUCK
+++ b/apps/l3vpn/BUCK
@@ -7,6 +7,8 @@
     '//lib:onos-yang-model',
     '//lib:onos-yang-runtime',
     '//apps/yang:onos-apps-yang',
+    '//apps/pce/app:onos-apps-pce-app',
+    '//incubator/api:onos-incubator-api'
 ]
 
 TEST_DEPS = [
diff --git a/apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/BgpDriverInfo.java b/apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/BgpDriverInfo.java
index 13bc818..54ee93a 100644
--- a/apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/BgpDriverInfo.java
+++ b/apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/BgpDriverInfo.java
@@ -24,7 +24,7 @@
     /**
      * Model id level of the BGP information that needed to be added in store.
      */
-    private BgpModelIdLevel modIdLevel;
+    private ModelIdLevel modIdLevel;
 
     /**
      * Device id required for the creation of driver model object data.
@@ -37,7 +37,7 @@
      * @param m model id level for BGP
      * @param d device id
      */
-    public BgpDriverInfo(BgpModelIdLevel m, String d) {
+    public BgpDriverInfo(ModelIdLevel m, String d) {
         modIdLevel = m;
         devId = d;
     }
@@ -47,7 +47,7 @@
      *
      * @return model id level
      */
-    public BgpModelIdLevel modIdLevel() {
+    public ModelIdLevel modIdLevel() {
         return modIdLevel;
     }
 
diff --git a/apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/DeviceInfo.java b/apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/DeviceInfo.java
index 20cf1c5..9a2c49a 100644
--- a/apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/DeviceInfo.java
+++ b/apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/DeviceInfo.java
@@ -17,7 +17,6 @@
 package org.onosproject.l3vpn.netl3vpn;
 
 import org.onosproject.net.DeviceId;
-import org.onosproject.net.behaviour.L3VpnConfig;
 import org.onosproject.net.driver.DriverHandler;
 import org.onosproject.net.driver.DriverService;
 import org.onosproject.yang.model.ModelObjectData;
@@ -37,6 +36,11 @@
     private final DeviceId deviceId;
 
     /**
+     * Type of the VPN.
+     */
+    private final VpnType type;
+
+    /**
      * BGP information of the device.
      */
     private BgpInfo bgpInfo;
@@ -52,12 +56,24 @@
     private List<AccessInfo> accesses;
 
     /**
-     * Constructs device info with a device id.
+     * List of tunnel names belonging to the device.
+     */
+    private List<String> tnlNames;
+
+    /**
+     * Status of tunnel policy being created for this device in this VPN.
+     */
+    private boolean isTnlPolCreated;
+
+    /**
+     * Constructs device info with a device id and VPN type.
      *
      * @param d device id
+     * @param t VPN type
      */
-    public DeviceInfo(DeviceId d) {
+    public DeviceInfo(DeviceId d, VpnType t) {
         deviceId = d;
+        type = t;
     }
 
     /**
@@ -70,6 +86,15 @@
     }
 
     /**
+     * Returns the type of the VPN instance.
+     *
+     * @return VPN type
+     */
+    public VpnType type() {
+        return type;
+    }
+
+    /**
      * Adds a interface name to the list.
      *
      * @param ifName interface name
@@ -99,6 +124,56 @@
         this.ifNames = ifNames;
     }
 
+    /***
+     * Returns the list of tunnel names.
+     *
+     * @return tunnel names
+     */
+    public List<String> tnlNames() {
+        return tnlNames;
+    }
+
+    /**
+     * Sets the list of tunnel names.
+     *
+     * @param tnlNames tunnel names
+     */
+    public void tnlNames(List<String> tnlNames) {
+        this.tnlNames = tnlNames;
+    }
+
+    /**
+     * Adds a tunnel name to the list.
+     *
+     * @param tnlName tunnel name
+     */
+    public void addTnlName(String tnlName) {
+        if (tnlNames == null) {
+            tnlNames = new LinkedList<>();
+        }
+        tnlNames.add(tnlName);
+    }
+
+    /**
+     * Returns true if tunnel policy is created for this device in this VPN;
+     * false otherwise.
+     *
+     * @return true if tunnel policy is created; false otherwise
+     */
+    public boolean isTnlPolCreated() {
+        return isTnlPolCreated;
+    }
+
+    /**
+     * Sets true if tunnel policy is created for this device in this VPN;
+     * false otherwise.
+     *
+     * @param tnlPolCreated status of tunnel policy creation
+     */
+    public void setTnlPolCreated(boolean tnlPolCreated) {
+        isTnlPolCreated = tnlPolCreated;
+    }
+
     /**
      * Returns the BGP information.
      *
@@ -159,7 +234,7 @@
     public ModelObjectData processCreateInstance(DriverService driverSvc,
                                                  ModelObjectData modelData) {
         L3VpnConfig config = getL3VpnConfig(driverSvc);
-        return (ModelObjectData) config.createInstance(modelData);
+        return config.createInstance(modelData);
     }
 
     /**
@@ -174,7 +249,7 @@
     public ModelObjectData processCreateInterface(DriverService driverSvc,
                                                   ModelObjectData modData) {
         L3VpnConfig config = getL3VpnConfig(driverSvc);
-        return (ModelObjectData) config.bindInterface(modData);
+        return config.bindInterface(modData);
     }
 
     /**
@@ -191,7 +266,67 @@
                                                 BgpInfo bgpInfo,
                                                 BgpDriverInfo driverInfo) {
         L3VpnConfig config = getL3VpnConfig(driverSvc);
-        return (ModelObjectData) config.createBgpInfo(bgpInfo, driverInfo);
+        return config.createBgpInfo(bgpInfo, driverInfo);
+    }
+
+    /**
+     * Processes the creation of tunnel tree from the devices and device
+     * level. It returns the tunnel info with devices and device of driver
+     * constructed model object data.
+     *
+     * @param driverSvc driver service
+     * @param tnlInfo   tunnel info
+     * @return driver model object data of tunnel info with devices and device
+     */
+    public ModelObjectData processCreateTnlDev(DriverService driverSvc,
+                                               TunnelInfo tnlInfo) {
+        L3VpnConfig config = getL3VpnConfig(driverSvc);
+        return config.createTnlDev(tnlInfo);
+    }
+
+    /**
+     * Processes the creation of tunnel policy in the tree from the tunnel
+     * manager or tunnel policy level. It returns the tunnel info with
+     * tunnel policy level of driver constructed model object data.
+     *
+     * @param driverSvc driver service
+     * @param tnlInfo   tunnel info
+     * @return driver model object data of tunnel info with tunnel policy
+     */
+    public ModelObjectData processCreateTnlPol(DriverService driverSvc,
+                                               TunnelInfo tnlInfo) {
+        L3VpnConfig config = getL3VpnConfig(driverSvc);
+        return config.createTnlPol(tnlInfo);
+    }
+
+    /**
+     * Processes the creation of tunnel in the tree from the tunnel next hops
+     * or only tunnel next hop. It returns the tunnel info with tunnel level
+     * of driver constructed model object data
+     *
+     * @param driverSvc driver service
+     * @param tnlInfo   tunnel info
+     * @return driver model object data of tunnel info with tunnel
+     */
+    public ModelObjectData processCreateTnl(DriverService driverSvc,
+                                            TunnelInfo tnlInfo) {
+        L3VpnConfig config = getL3VpnConfig(driverSvc);
+        return config.createTnl(tnlInfo);
+    }
+
+    /**
+     * Processes the binding of tunnel policy to the VPN instance. It returns
+     * the VPN instance with tunnel policy of driver constructed model object
+     * data.
+     *
+     * @param driverSvc driver service
+     * @param tnlInfo   tunnel info
+     * @return driver model object data of VPN instance with tunnel
+     */
+    public ModelObjectData processBindTnl(DriverService driverSvc,
+                                          TunnelInfo tnlInfo) {
+        L3VpnConfig config = getL3VpnConfig(driverSvc);
+        return config.bindTnl(tnlInfo);
     }
 
     /**
@@ -206,7 +341,7 @@
     public ModelObjectData processDeleteInstance(DriverService driverSvc,
                                                  ModelObjectData modData) {
         L3VpnConfig config = getL3VpnConfig(driverSvc);
-        return (ModelObjectData) config.deleteInstance(modData);
+        return config.deleteInstance(modData);
     }
 
     /**
@@ -238,7 +373,22 @@
                                                 BgpInfo bgpInfo,
                                                 BgpDriverInfo driverInfo) {
         L3VpnConfig config = getL3VpnConfig(driverSvc);
-        return (ModelObjectData) config.deleteBgpInfo(bgpInfo, driverInfo);
+        return config.deleteBgpInfo(bgpInfo, driverInfo);
+    }
+
+    /**
+     * Processes the deletion of tunnel info according to the levels it has
+     * to be deleted. It returns the tunnel info of driver constructed model
+     * object data.
+     *
+     * @param driverSvc driver service
+     * @param tnlInfo   tunnel info
+     * @return driver tunnel info model object data
+     */
+    public ModelObjectData processDeleteTnl(DriverService driverSvc,
+                                            TunnelInfo tnlInfo) {
+        L3VpnConfig config = getL3VpnConfig(driverSvc);
+        return config.deleteTnl(tnlInfo);
     }
 
     /**
diff --git a/apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/L3VpnConfig.java b/apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/L3VpnConfig.java
new file mode 100644
index 0000000..bfc8164
--- /dev/null
+++ b/apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/L3VpnConfig.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.l3vpn.netl3vpn;
+
+import org.onosproject.net.driver.HandlerBehaviour;
+import org.onosproject.yang.model.ModelObjectData;
+
+/**
+ * Behaviour for handling various drivers for l3vpn configurations.
+ */
+public interface L3VpnConfig extends HandlerBehaviour {
+
+    /**
+     * Create virtual routing forwarding instance on requested device with
+     * given standard device model object data.
+     *
+     * @param objectData standard device model object data
+     * @return device model object data
+     */
+    ModelObjectData createInstance(ModelObjectData objectData);
+
+    /**
+     * Binds requested virtual routing forwarding instance to interface on the
+     * requested device with given standard device model object data.
+     *
+     * @param objectData standard device model object data
+     * @return device model object data
+     */
+    ModelObjectData bindInterface(ModelObjectData objectData);
+
+    /**
+     * Deletes virtual routing forwarding instance on requested device with
+     * given standard device model object data.
+     *
+     * @param objectData standard device model object data
+     * @return device model object data
+     */
+    ModelObjectData deleteInstance(ModelObjectData objectData);
+
+    /**
+     * Unbinds requested virtual routing forwarding instance to interface on the
+     * requested device with given standard device model object data.
+     *
+     * @param objectData standard device model object data
+     * @return device model object data
+     */
+    ModelObjectData unbindInterface(ModelObjectData objectData);
+
+    /**
+     * Deletes tunnel on requested device with the given tunnel info.
+     *
+     * @param tnlInfo tunnel info
+     * @return device model object data
+     */
+    ModelObjectData deleteTnl(TunnelInfo tnlInfo);
+
+    /**
+     * Creates BGP routing protocol info on requested device with given
+     * BGP info object.
+     *
+     * @param bgpInfo   BGP info object
+     * @param bgpConfig BGP driver config
+     * @return device model object data
+     */
+    ModelObjectData createBgpInfo(BgpInfo bgpInfo, BgpDriverInfo bgpConfig);
+
+    /**
+     * Deletes BGP routing protocol info on requested device with given
+     * BGP info object.
+     *
+     * @param bgpInfo   BGP info object
+     * @param bgpConfig BGP driver config
+     * @return device model object data
+     */
+    ModelObjectData deleteBgpInfo(BgpInfo bgpInfo, BgpDriverInfo bgpConfig);
+
+    /**
+     * Creates device and devices level on requested device for tunnel creation.
+     *
+     * @param tnlInfo tunnel info
+     * @return device model object data
+     */
+    ModelObjectData createTnlDev(TunnelInfo tnlInfo);
+
+    /**
+     * Creates tunnel policy on requested device with given tunnel info.
+     *
+     * @param tnlInfo tunnel info
+     * @return device model object data
+     */
+    ModelObjectData createTnlPol(TunnelInfo tnlInfo);
+
+    /**
+     * Creates tunnel on requested device with given tunnel info.
+     *
+     * @param tnlInfo tunnel info
+     * @return device model object data
+     */
+    ModelObjectData createTnl(TunnelInfo tnlInfo);
+
+    /**
+     * Binds requested tunnel policy name to the VPN to the requested device
+     * with given tunnel info.
+     *
+     * @param tnlInfo tunnel info
+     * @return device model object data
+     */
+    ModelObjectData bindTnl(TunnelInfo tnlInfo);
+}
diff --git a/apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/BgpModelIdLevel.java b/apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/ModelIdLevel.java
similarity index 73%
rename from apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/BgpModelIdLevel.java
rename to apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/ModelIdLevel.java
index e5c76b1..91bf248 100644
--- a/apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/BgpModelIdLevel.java
+++ b/apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/ModelIdLevel.java
@@ -17,10 +17,10 @@
 package org.onosproject.l3vpn.netl3vpn;
 
 /**
- * Represents the model id level of BGP information to be added to store.
- * //TODO: Further more levels of BGP addition has to be added.
+ * Represents the model id level to add it in the store.
+ * //TODO: Further levels has to be added.
  */
-public enum BgpModelIdLevel {
+public enum ModelIdLevel {
 
     /**
      * Requested model id level is not present, representing top node.
@@ -40,5 +40,20 @@
     /**
      * Requested model id level is VPN list.
      */
-    VPN
+    VPN,
+
+    /**
+     * Requested model id level is tunnel manager.
+     */
+    TNL_M,
+
+    /**
+     * Requested model id level is tunnel policy.
+     */
+    TNL_POL,
+
+    /**
+     * Requested model id level is tunnel hop.
+     */
+    TP_HOP
 }
diff --git a/apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/NetL3VpnStore.java b/apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/NetL3VpnStore.java
index 8d63809..db926a2 100644
--- a/apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/NetL3VpnStore.java
+++ b/apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/NetL3VpnStore.java
@@ -55,6 +55,13 @@
     Map<AccessInfo, InterfaceInfo> getInterfaceInfo();
 
     /**
+     * Returns the tunnel information map available in the store, for a device.
+     *
+     * @return tunnel info map
+     */
+    Map<DeviceId, Integer> getTunnelInfo();
+
+    /**
      * Adds freed id to the freed list in the store.
      *
      * @param id id
@@ -95,6 +102,14 @@
     void addBgpInfo(BgpInfo bgpInfo, DeviceId devId);
 
     /**
+     * Adds the device id and the number of tunnels created for that device.
+     *
+     * @param devId device id
+     * @param count number of tunnels
+     */
+    void addTunnelInfo(DeviceId devId, Integer count);
+
+    /**
      * Removes the interface info with the key access info from the store.
      *
      * @param accessInfo access info
@@ -127,4 +142,13 @@
      * @return true if removed; false otherwise
      */
     boolean removeBgpInfo(BgpInfo bgpInfo);
+
+    /**
+     * Removes the device id from the store with the value count of number of
+     * tunnels.
+     *
+     * @param id device id
+     * @return true if removed; false otherwise
+     */
+    boolean removeTunnelInfo(DeviceId id);
 }
diff --git a/apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/TunnelInfo.java b/apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/TunnelInfo.java
new file mode 100644
index 0000000..db8c9c6
--- /dev/null
+++ b/apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/TunnelInfo.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.l3vpn.netl3vpn;
+
+/**
+ * Represents the tunnel information.
+ */
+public class TunnelInfo {
+
+    /**
+     * Destination ip address.
+     */
+    private final String desIp;
+
+    /**
+     * Tunnel name.
+     */
+    private final String tnlName;
+
+    /**
+     * Tunnel policy name.
+     */
+    private final String polName;
+
+    /**
+     * Device id.
+     */
+    private final String devId;
+
+    /**
+     * Level of the model.
+     */
+    private ModelIdLevel level;
+
+    /**
+     * Creates tunnel info with destination ip address, tunnel name, tunnel
+     * policy name and device id.
+     *
+     * @param dIp   destination ip
+     * @param tName tunnel name
+     * @param pName tunnel policy name
+     * @param dId   device id
+     */
+    public TunnelInfo(String dIp, String tName, String pName, String dId) {
+        this.desIp = dIp;
+        this.tnlName = tName;
+        this.polName = pName;
+        this.devId = dId;
+    }
+
+    /**
+     * Returns the destination ip-address.
+     *
+     * @return destination ip-address
+     */
+    public String desIp() {
+        return desIp;
+    }
+
+    /**
+     * Returns the tunnel name.
+     *
+     * @return tunnel name
+     */
+    public String tnlName() {
+        return tnlName;
+    }
+
+    /**
+     * Returns the tunnel policy name.
+     *
+     * @return tunnel policy name
+     */
+    public String polName() {
+        return polName;
+    }
+
+    /**
+     * Returns the device id.
+     *
+     * @return device id
+     */
+    public String devId() {
+        return devId;
+    }
+
+    /**
+     * Returns the model id level.
+     *
+     * @return model id level
+     */
+    public ModelIdLevel level() {
+        return level;
+    }
+
+    /**
+     * Sets the model id level.
+     *
+     * @param level model id level
+     */
+    public void level(ModelIdLevel level) {
+        this.level = level;
+    }
+}
diff --git a/apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/DistributedNetL3VpnStore.java b/apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/DistributedNetL3VpnStore.java
index 6fa2cfd..28a90da 100644
--- a/apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/DistributedNetL3VpnStore.java
+++ b/apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/DistributedNetL3VpnStore.java
@@ -32,6 +32,7 @@
 import org.onosproject.l3vpn.netl3vpn.NetL3VpnStore;
 import org.onosproject.l3vpn.netl3vpn.ProtocolInfo;
 import org.onosproject.l3vpn.netl3vpn.RouteProtocol;
+import org.onosproject.l3vpn.netl3vpn.TunnelInfo;
 import org.onosproject.l3vpn.netl3vpn.VpnConfig;
 import org.onosproject.l3vpn.netl3vpn.VpnInstance;
 import org.onosproject.l3vpn.netl3vpn.VpnType;
@@ -81,6 +82,7 @@
                            .register(BgpInfo.class)
                            .register(RouteProtocol.class)
                            .register(ProtocolInfo.class)
+                           .register(TunnelInfo.class)
                            .build());
 
     private static final String FREE_ID_NULL = "Free ID cannot be null";
@@ -116,6 +118,11 @@
      */
     private ConsistentMap<BgpInfo, DeviceId> bgpInfoMap;
 
+    /**
+     * Map of device id and tunnel count.
+     */
+    private ConsistentMap<DeviceId, Integer> tunnelInfoMap;
+
     @Activate
     protected void activate() {
         vpnInsMap = storageService.<String, VpnInstance>consistentMapBuilder()
@@ -134,6 +141,11 @@
                 .withSerializer(L3VPN_SERIALIZER)
                 .build();
 
+        tunnelInfoMap = storageService.<DeviceId, Integer>consistentMapBuilder()
+                .withName("onos-l3vpn-tnl-info-map")
+                .withSerializer(L3VPN_SERIALIZER)
+                .build();
+
         freedIdList = storageService.<Long>setBuilder()
                 .withName("onos-l3vpn-id-freed-list")
                 .withSerializer(Serializer.using(KryoNamespaces.API))
@@ -175,6 +187,13 @@
     }
 
     @Override
+    public Map<DeviceId, Integer> getTunnelInfo() {
+        return tunnelInfoMap.entrySet().stream()
+                .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue()
+                        .value()));
+    }
+
+    @Override
     public void addIdToFreeList(Long id) {
         checkNotNull(id, FREE_ID_NULL);
         freedIdList.add(id);
@@ -203,12 +222,18 @@
 
     @Override
     public void addBgpInfo(BgpInfo bgpInfo, DeviceId devId) {
-        checkNotNull(devId, BGP_INFO_NULL);
+        checkNotNull(bgpInfo, BGP_INFO_NULL);
         checkNotNull(devId, DEV_ID_NULL);
         bgpInfoMap.put(bgpInfo, devId);
     }
 
     @Override
+    public void addTunnelInfo(DeviceId devId, Integer count) {
+        checkNotNull(devId, DEV_ID_NULL);
+        tunnelInfoMap.put(devId, count);
+    }
+
+    @Override
     public boolean removeInterfaceInfo(AccessInfo accessInfo) {
         checkNotNull(accessInfo, ACCESS_INFO_NULL);
 
@@ -255,4 +280,15 @@
         }
         return true;
     }
+
+    @Override
+    public boolean removeTunnelInfo(DeviceId id) {
+        checkNotNull(id, DEV_ID_NULL);
+
+        if (tunnelInfoMap.remove(id) == null) {
+            log.error("Device id deletion in tunnel info has failed.");
+            return false;
+        }
+        return true;
+    }
 }
diff --git a/apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/NetL3VpnManager.java b/apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/NetL3VpnManager.java
index cc0d51e..3b45c7d 100644
--- a/apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/NetL3VpnManager.java
+++ b/apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/NetL3VpnManager.java
@@ -48,11 +48,11 @@
 import org.onosproject.l3vpn.netl3vpn.VpnInstance;
 import org.onosproject.l3vpn.netl3vpn.VpnSiteRole;
 import org.onosproject.l3vpn.netl3vpn.VpnType;
-import org.onosproject.net.Device;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.Port;
 import org.onosproject.net.device.DeviceService;
 import org.onosproject.net.driver.DriverService;
+import org.onosproject.pce.pceservice.api.PceService;
 import org.onosproject.yang.gen.v1.ietfinterfaces.rev20140508.ietfinterfaces.devices.device.Interfaces;
 import org.onosproject.yang.gen.v1.ietfl3vpnsvc.rev20160730.ietfl3vpnsvc.DefaultL3VpnSvc;
 import org.onosproject.yang.gen.v1.ietfl3vpnsvc.rev20160730.ietfl3vpnsvc.L3VpnSvc;
@@ -67,8 +67,6 @@
 import org.onosproject.yang.gen.v1.ietfl3vpnsvc.rev20160730.ietfl3vpnsvc.l3vpnsvc.sites.site.sitenetworkaccesses.SiteNetworkAccess;
 import org.onosproject.yang.gen.v1.ietfl3vpnsvc.rev20160730.ietfl3vpnsvc.l3vpnsvc.vpnservices.VpnSvc;
 import org.onosproject.yang.gen.v1.ietfl3vpnsvc.rev20160730.ietfl3vpnsvc.siteattachmentbearer.Bearer;
-import org.onosproject.yang.gen.v1.ietfl3vpnsvc.rev20160730.ietfl3vpnsvc.siteattachmentbearer.DefaultBearer;
-import org.onosproject.yang.gen.v1.ietfl3vpnsvc.rev20160730.ietfl3vpnsvc.siteattachmentbearer.bearer.DefaultRequestedType;
 import org.onosproject.yang.gen.v1.ietfl3vpnsvc.rev20160730.ietfl3vpnsvc.siteattachmentbearer.bearer.RequestedType;
 import org.onosproject.yang.gen.v1.ietfl3vpnsvc.rev20160730.ietfl3vpnsvc.siteattachmentipconnection.IpConnection;
 import org.onosproject.yang.gen.v1.ietfl3vpnsvc.rev20160730.ietfl3vpnsvc.siterouting.RoutingProtocols;
@@ -111,7 +109,6 @@
 import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.ID_LIMIT;
 import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.ID_LIMIT_EXCEEDED;
 import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.INT_INFO_NULL;
-import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.IP;
 import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.IP_INT_INFO_NULL;
 import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.MAX_BATCH_MS;
 import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.MAX_EVENTS;
@@ -125,9 +122,9 @@
 import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.VPN_POLICY_NOT_SUPPORTED;
 import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.VPN_TYPE_UNSUPPORTED;
 import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getBgpCreateConfigObj;
+import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getId;
 import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getIntCreateModObj;
 import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getIntNotAvailable;
-import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getMgmtIpUnAvailErr;
 import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getModIdForL3VpnSvc;
 import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getModIdForSites;
 import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getResourceData;
@@ -144,6 +141,7 @@
 
     private static final String APP_ID = "org.onosproject.app.l3vpn";
     private static final String L3_VPN_ID_TOPIC = "l3vpn-id";
+    private static final String TNL_ID_TOPIC = "l3vpn-tnl-id";
 
     private final Logger log = LoggerFactory.getLogger(getClass());
 
@@ -180,8 +178,13 @@
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected ClusterService clusterService;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected PceService pceService;
+
     protected IdGenerator l3VpnIdGen;
 
+    protected IdGenerator tnlIdGen;
+
     private NodeId localNodeId;
 
     private ApplicationId appId;
@@ -194,15 +197,21 @@
 
     private boolean isElectedLeader;
 
+    private NetL3VpnTunnelHandler tnlHandler;
+
     @Activate
     protected void activate() {
         appId = coreService.registerApplication(APP_ID);
         l3VpnIdGen = coreService.getIdGenerator(L3_VPN_ID_TOPIC);
+        tnlIdGen = coreService.getIdGenerator(TNL_ID_TOPIC);
         localNodeId = clusterService.getLocalNode().id();
         leadershipService.addListener(leadershipEventListener);
         leadershipService.runForLeadership(appId.name());
         getResourceId();
         configService.addListener(configListener);
+        tnlHandler = new NetL3VpnTunnelHandler(
+                pceService, driverService, configService, l3VpnStore,
+                deviceService, tnlIdGen, modelConverter);
         log.info("Started");
     }
 
@@ -526,8 +535,8 @@
      */
     private DeviceInfo buildDevVpnIns(Bearer bearer, VpnInstance ins,
                                       VpnSiteRole role, IpConnection connect) {
-        DefaultAugmentedL3VpnBearer augBearer = ((DefaultBearer) bearer)
-                .augmentation(DefaultAugmentedL3VpnBearer.class);
+        DefaultAugmentedL3VpnBearer augBearer = bearer.augmentation(
+                DefaultAugmentedL3VpnBearer.class);
         DeviceId id = getDeviceId(augBearer);
         Map<DeviceId, DeviceInfo> devices = ins.devInfo();
         DeviceInfo info = null;
@@ -554,24 +563,7 @@
             throw new NetL3VpnException(DEVICE_INFO_NULL);
         }
         String ip = attach.bearerAttachment().peMgmtIp().string();
-        return getId(ip);
-    }
-
-    /**
-     * Returns the device id whose management ip address matches with the ip
-     * received.
-     *
-     * @param ip ip address
-     * @return device id
-     */
-    public DeviceId getId(String ip) {
-        for (Device device : deviceService.getAvailableDevices()) {
-            String val = device.annotations().value(IP);
-            if (ip.equals(val)) {
-                return device.id();
-            }
-        }
-        throw new NetL3VpnException(getMgmtIpUnAvailErr(ip));
+        return getId(ip, true, deviceService.getAvailableDevices());
     }
 
     /**
@@ -588,21 +580,46 @@
                                          VpnInstance inst, IpConnection ip) {
         Map<AccessInfo, InterfaceInfo> intMap = l3VpnStore.getInterfaceInfo();
         generateRdRt(inst, role);
-        DeviceInfo info = new DeviceInfo(id);
+        DeviceInfo info = new DeviceInfo(id, role.role());
 
         NetworkInstances instances = createInstance(inst, role, ip);
         ModelObjectData devMod = getVpnCreateModObj(intMap, instances,
                                                     id.toString());
+        inst.addDevInfo(id, info);
+        l3VpnStore.addVpnIns(inst.vpnName(), inst);
+
         ModelObjectData driMod = info.processCreateInstance(driverService,
                                                             devMod);
         ResourceData resData = modelConverter.createDataNode(driMod);
         addToStore(resData);
-        l3VpnStore.addVpnIns(inst.vpnName(), inst);
-        inst.addDevInfo(id, info);
+        checkAndUpdateTunnel(inst, id);
         return info;
     }
 
     /**
+     * Checks if the tunnel can be established and creates the tunnel from
+     * source to destination.
+     *
+     * @param inst VPN instance
+     * @param id   device id
+     */
+    private void checkAndUpdateTunnel(VpnInstance inst, DeviceId id) {
+        Map<DeviceId, DeviceInfo> devInfo = inst.devInfo();
+        int devSize = devInfo.size();
+        String vpnName = inst.vpnName();
+        if (devSize != 1) {
+            DeviceInfo info = devInfo.get(id);
+            tnlHandler.createSrcInfo(vpnName, info);
+            for (Map.Entry<DeviceId, DeviceInfo> device : devInfo.entrySet()) {
+                DeviceInfo val = device.getValue();
+                if (val != info) {
+                    tnlHandler.createSrcDesTunnel(val);
+                }
+            }
+        }
+    }
+
+    /**
      * Adds the resource data that is received from the driver, after
      * converting from the model object data.
      *
@@ -737,9 +754,8 @@
      * @return interface name
      */
     private String getInterfaceName(DeviceInfo info, RequestedType reqType) {
-        DefaultAugmentedL3VpnRequestedType req =
-                ((DefaultRequestedType) reqType).augmentation(
-                        DefaultAugmentedL3VpnRequestedType.class);
+        DefaultAugmentedL3VpnRequestedType req = reqType.augmentation(
+                DefaultAugmentedL3VpnRequestedType.class);
         if (req == null || req.requestedTypeProfile() == null ||
                 req.requestedTypeProfile().requestedTypeChoice() == null) {
             throw new NetL3VpnException(INT_INFO_NULL);
@@ -925,6 +941,7 @@
                         driverService, devMod);
                 ResourceData resData = modelConverter.createDataNode(driMod);
                 deleteFromStore(resData);
+                tnlHandler.deleteTunnel(dev, instance.vpnName());
             }
             l3VpnStore.removeVpnInstance(instance.vpnName());
         }
diff --git a/apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/NetL3VpnTunnelHandler.java b/apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/NetL3VpnTunnelHandler.java
new file mode 100644
index 0000000..edef00a
--- /dev/null
+++ b/apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/NetL3VpnTunnelHandler.java
@@ -0,0 +1,329 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.l3vpn.netl3vpn.impl;
+
+import org.onosproject.config.DynamicConfigService;
+import org.onosproject.core.IdGenerator;
+import org.onosproject.incubator.net.tunnel.Tunnel;
+import org.onosproject.l3vpn.netl3vpn.DeviceInfo;
+import org.onosproject.l3vpn.netl3vpn.ModelIdLevel;
+import org.onosproject.l3vpn.netl3vpn.NetL3VpnException;
+import org.onosproject.l3vpn.netl3vpn.NetL3VpnStore;
+import org.onosproject.l3vpn.netl3vpn.TunnelInfo;
+import org.onosproject.l3vpn.netl3vpn.VpnType;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.driver.DriverService;
+import org.onosproject.pce.pceservice.api.PceService;
+import org.onosproject.yang.model.DataNode;
+import org.onosproject.yang.model.ModelConverter;
+import org.onosproject.yang.model.ModelObjectData;
+import org.onosproject.yang.model.ResourceData;
+
+import java.util.List;
+import java.util.Map;
+
+import static org.onosproject.l3vpn.netl3vpn.ModelIdLevel.DEVICE;
+import static org.onosproject.l3vpn.netl3vpn.ModelIdLevel.DEVICES;
+import static org.onosproject.l3vpn.netl3vpn.ModelIdLevel.TNL_M;
+import static org.onosproject.l3vpn.netl3vpn.ModelIdLevel.TNL_POL;
+import static org.onosproject.l3vpn.netl3vpn.ModelIdLevel.TP_HOP;
+import static org.onosproject.l3vpn.netl3vpn.VpnType.SPOKE;
+import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.NEW_NAME;
+import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getId;
+import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getIpFromDevId;
+import static org.onosproject.pce.pceservice.LspType.WITH_SIGNALLING;
+
+/**
+ * Represents net l3VPN tunnel handler, which handles tunnel operations like
+ * creation and deletion and updating it to the driver.
+ */
+public class NetL3VpnTunnelHandler {
+
+    private PceService pceSvc;
+    private DriverService driSvc;
+    private DynamicConfigService configSvc;
+    private NetL3VpnStore store;
+    private DeviceService devSvc;
+    private IdGenerator tnlIdGen;
+    private ModelConverter modelCon;
+    private String sIp;
+    private String vpnName;
+    private DeviceInfo sInfo;
+    private VpnType type;
+
+    /**
+     * Constructs net l3VPN tunnel handler with required services.
+     *
+     * @param p   pce service
+     * @param d   driver service
+     * @param c   dynamic config service
+     * @param s   net l3VPN store
+     * @param dev device service
+     * @param id  ID generator
+     * @param m   model converter
+     */
+    public NetL3VpnTunnelHandler(PceService p, DriverService d,
+                                 DynamicConfigService c,
+                                 NetL3VpnStore s, DeviceService dev,
+                                 IdGenerator id, ModelConverter m) {
+        pceSvc = p;
+        driSvc = d;
+        configSvc = c;
+        store = s;
+        devSvc = dev;
+        tnlIdGen = id;
+        modelCon = m;
+    }
+
+    /**
+     * Creates the source information for tunnel creation. It creates from
+     * source device info and VPN name.
+     *
+     * @param vName   VPN name
+     * @param devInfo device info
+     */
+    public void createSrcInfo(String vName, DeviceInfo devInfo) {
+        vpnName = vName;
+        sInfo = devInfo;
+        type = devInfo.type();
+        sIp = getIpFromDevId(sInfo.deviceId());
+    }
+
+    /**
+     * Creates tunnel between source and destination devices.
+     *
+     * @param dInfo destination device
+     */
+    public void createSrcDesTunnel(DeviceInfo dInfo) {
+        VpnType dType = dInfo.type();
+        if (type == SPOKE && dType == SPOKE) {
+            return;
+        }
+        String dIp = getIpFromDevId(dInfo.deviceId());
+        createTunnelInfo(sIp, dIp, sInfo);
+        createTunnelInfo(dIp, sIp, dInfo);
+    }
+
+    /**
+     * Creates tunnel info and tunnel based on source and destination ip
+     * address and configures it in the source device.
+     *
+     * @param sIp   source ip address
+     * @param dIp   destination ip address
+     * @param sInfo source device info
+     */
+    private void createTunnelInfo(String sIp, String dIp, DeviceInfo sInfo) {
+        DeviceId id = sInfo.deviceId();
+        Map<DeviceId, Integer> tnlMap = store.getTunnelInfo();
+        int count = 0;
+        if (tnlMap.containsKey(id)) {
+            count = tnlMap.get(id);
+        }
+        String tnlName = createTunnel(sIp, dIp);
+        sInfo.addTnlName(tnlName);
+        store.addTunnelInfo(id, count + 1);
+        TunnelInfo tnl = new TunnelInfo(dIp, tnlName, vpnName, id.toString());
+        configureDevTnl(sInfo, tnl, tnlMap);
+    }
+
+    /**
+     * Creates tunnel between source ip address and destination ip address
+     * with pce service.
+     *
+     * @param srcIp source ip address
+     * @param desIp destination ip address
+     * @return tunnel name
+     */
+    private String createTunnel(String srcIp, String desIp) {
+        Iterable<Device> devices = devSvc.getAvailableDevices();
+        DeviceId srcDevId = getId(srcIp, false, devices);
+        DeviceId desDevId = getId(desIp, false, devices);
+        String name = getNewName();
+        boolean isCreated = pceSvc.setupPath(srcDevId, desDevId, name,
+                                             null, WITH_SIGNALLING);
+        if (!isCreated) {
+            throw new NetL3VpnException("Tunnel is not created between " +
+                                                srcDevId.toString() + " and " +
+                                                desDevId.toString());
+        }
+        return name;
+    }
+
+    /**
+     * Returns a unique name for tunnel to be created.
+     *
+     * @return unique tunnel name
+     */
+    private String getNewName() {
+        return NEW_NAME + String.valueOf(tnlIdGen.getNewId());
+    }
+
+    /**
+     * Configures the created tunnel to the device by processing it at the
+     * proper level and sending it to the driver.
+     *
+     * @param info    source device info
+     * @param tnlInfo tunnel info
+     * @param tnlMap  store tunnel map
+     */
+    private void configureDevTnl(DeviceInfo info, TunnelInfo tnlInfo,
+                                 Map<DeviceId, Integer> tnlMap) {
+        DeviceId id = info.deviceId();
+        int count = 0;
+        if (tnlMap.containsKey(id)) {
+            count = tnlMap.get(id);
+        }
+        if (tnlMap.size() == 0) {
+            tnlInfo.level(DEVICES);
+        } else if (count == 0) {
+            tnlInfo.level(DEVICE);
+        }
+
+        if (tnlInfo.level() != null) {
+            ModelObjectData mod = info.processCreateTnlDev(driSvc, tnlInfo);
+            addDataNodeToStore(mod);
+            tnlInfo.level(TNL_M);
+            tnlPolToStore(info, tnlInfo);
+        }
+        if (!info.isTnlPolCreated()) {
+            tnlInfo.level(TNL_POL);
+            tnlPolToStore(info, tnlInfo);
+        }
+        if (tnlInfo.level() == null) {
+            tnlInfo.level(TP_HOP);
+        }
+
+        ModelObjectData tnlMod = info.processCreateTnl(driSvc, tnlInfo);
+        addDataNodeToStore(tnlMod);
+        if (tnlInfo.level() != TP_HOP) {
+            ModelObjectData mod = info.processBindTnl(driSvc, tnlInfo);
+            addDataNodeToStore(mod);
+        }
+    }
+
+    /**
+     * Adds data node to the store after converting it to the resource data.
+     *
+     * @param driMod driver model object data
+     */
+    private void addDataNodeToStore(ModelObjectData driMod) {
+        ResourceData resData = modelCon.createDataNode(driMod);
+        addToStore(resData);
+    }
+
+    /**
+     * Adds resource data to the store.
+     *
+     * @param resData resource data
+     */
+    private void addToStore(ResourceData resData) {
+        if (resData != null && resData.dataNodes() != null) {
+            List<DataNode> dataNodes = resData.dataNodes();
+            for (DataNode node : dataNodes) {
+                configSvc.createNode(resData.resourceId(), node);
+            }
+        }
+    }
+
+    /**
+     * Creates tunnel policy from driver and adds it to the store.
+     *
+     * @param info    device info
+     * @param tnlInfo tunnel info
+     */
+    private void tnlPolToStore(DeviceInfo info, TunnelInfo tnlInfo) {
+        ModelObjectData mod = info.processCreateTnlPol(driSvc, tnlInfo);
+        addDataNodeToStore(mod);
+        info.setTnlPolCreated(true);
+    }
+
+    /**
+     * Deletes the tunnel with the source tunnel info and VPN name.
+     * //FIXME: PCE does'nt have api, which can give tunnel by providing the
+     * tunnel name.
+     *
+     * @param info  device info
+     * @param vName VPN name
+     */
+    public void deleteTunnel(DeviceInfo info, String vName) {
+        List<String> tnlNames = info.tnlNames();
+        for (String tnlName : tnlNames) {
+            Iterable<Tunnel> path = pceSvc.queryAllPath();
+            for (Tunnel tnl : path) {
+                if (tnl.tunnelName().toString().equals(tnlName)) {
+                    pceSvc.releasePath(tnl.tunnelId());
+                    break;
+                }
+            }
+        }
+        deleteFromDevice(info, vName);
+    }
+
+    /**
+     * Deletes tunnel configuration from the device by updating various
+     * levels in the store.
+     *
+     * @param info  device info
+     * @param vName VPN name
+     */
+    private void deleteFromDevice(DeviceInfo info, String vName) {
+        Map<DeviceId, Integer> map = store.getTunnelInfo();
+        DeviceId id = info.deviceId();
+        Integer count = map.get(id);
+        int tnlCount = info.tnlNames().size();
+        int upCount = count - tnlCount;
+        ModelIdLevel level;
+        TunnelInfo tnlInfo = new TunnelInfo(null, null, vName, id.toString());
+        if (upCount == 0) {
+            if (map.size() == 1) {
+                level = DEVICES;
+            } else {
+                level = DEVICE;
+            }
+        } else {
+            if (map.size() > 1) {
+                level = TNL_POL;
+            } else {
+                return;
+            }
+        }
+        tnlInfo.level(level);
+        ModelObjectData mod = info.processDeleteTnl(driSvc, tnlInfo);
+        deleteFromStore(mod);
+        info.tnlNames(null);
+        info.setTnlPolCreated(false);
+        if (upCount == 0) {
+            store.removeTunnelInfo(id);
+        } else {
+            store.addTunnelInfo(id, upCount);
+        }
+    }
+
+    /**
+     * Deletes the data node from the store.
+     *
+     * @param mod driver model object data
+     */
+    private void deleteFromStore(ModelObjectData mod) {
+        ResourceData resData = modelCon.createDataNode(mod);
+        if (resData != null) {
+            configSvc.deleteNode(resData.resourceId());
+        }
+    }
+}
diff --git a/apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/NetL3VpnUtil.java b/apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/NetL3VpnUtil.java
index 1dbb008..1fd03bd 100644
--- a/apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/NetL3VpnUtil.java
+++ b/apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/NetL3VpnUtil.java
@@ -46,10 +46,10 @@
 import java.util.List;
 import java.util.Map;
 
-import static org.onosproject.l3vpn.netl3vpn.BgpModelIdLevel.DEVICE;
-import static org.onosproject.l3vpn.netl3vpn.BgpModelIdLevel.DEVICES;
-import static org.onosproject.l3vpn.netl3vpn.BgpModelIdLevel.ROOT;
-import static org.onosproject.l3vpn.netl3vpn.BgpModelIdLevel.VPN;
+import static org.onosproject.l3vpn.netl3vpn.ModelIdLevel.DEVICE;
+import static org.onosproject.l3vpn.netl3vpn.ModelIdLevel.DEVICES;
+import static org.onosproject.l3vpn.netl3vpn.ModelIdLevel.ROOT;
+import static org.onosproject.l3vpn.netl3vpn.ModelIdLevel.VPN;
 import static org.onosproject.l3vpn.netl3vpn.VpnType.ANY_TO_ANY;
 import static org.onosproject.l3vpn.netl3vpn.VpnType.HUB;
 import static org.onosproject.l3vpn.netl3vpn.VpnType.SPOKE;
@@ -112,6 +112,11 @@
     static final String IP = "ipaddress";
 
     /**
+     * Static constant value for lsr id.
+     */
+    static final String LSR_ID = "lsrId";
+
+    /**
      * Error message for VPN type being not supported.
      */
     static final String VPN_TYPE_UNSUPPORTED = "The VPN type is not supported";
@@ -169,11 +174,17 @@
      */
     static final String EVENT_NULL = "Event cannot be null";
 
+    /**
+     * Unique tunnel name for net-l3VPN.
+     */
+    static final String NEW_NAME = "onos-netl3vpn";
+
     private static final String SITE_ROLE_INVALID = "The given site role is " +
             "invalid";
     private static final String ANY_TO_ANY_ROLE = "AnyToAnyRole";
     private static final String HUB_ROLE = "HubRole";
     private static final String SPOKE_ROLE = "SpokeRole";
+    private static final String COLON = ":";
 
     // No instantiation.
     private NetL3VpnUtil() {
@@ -515,4 +526,42 @@
         }
         return driInfo;
     }
+
+    /**
+     * Returns the device id whose management ip address or lsr ID matches with
+     * the ip or lsr ID received respectively.
+     *
+     * @param ip      value of ip or lsr id
+     * @param isIp    if ip or lsr id
+     * @param devices available devices
+     * @return device id
+     */
+    static DeviceId getId(String ip, boolean isIp,
+                          Iterable<org.onosproject.net.Device> devices) {
+        for (org.onosproject.net.Device device : devices) {
+            String val;
+            if (isIp) {
+                val = device.annotations().value(IP);
+            } else {
+                val = device.annotations().value(LSR_ID);
+            }
+            if (ip.equals(val)) {
+                return device.id();
+            }
+        }
+        throw new NetL3VpnException(getMgmtIpUnAvailErr(ip));
+    }
+
+    /**
+     * Returns ip address from the device id by parsing.
+     *
+     * @param devId device id
+     * @return ip address
+     */
+    static String getIpFromDevId(DeviceId devId) {
+        String devKey = devId.toString();
+        int firstInd = devKey.indexOf(COLON);
+        int secInd = devKey.indexOf(COLON, firstInd + 1);
+        return devKey.substring(firstInd + 1, secInd);
+    }
 }