[ONOS-6191] NET L3VPN create operation support
Change-Id: I0ddbf88cae67fdaa0087551dd4b4d066dd3d6c22
diff --git a/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/AccessInfo.java b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/AccessInfo.java
index 3728cbe..d8f1504 100644
--- a/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/AccessInfo.java
+++ b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/AccessInfo.java
@@ -49,7 +49,7 @@
*
* @return site id
*/
- String siteId() {
+ public String siteId() {
return siteId;
}
@@ -58,7 +58,7 @@
*
* @return access id
*/
- String accessId() {
+ public String accessId() {
return accessId;
}
diff --git a/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/BgpDriverInfo.java b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/BgpDriverInfo.java
index 151f3e5..ec7058f 100644
--- a/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/BgpDriverInfo.java
+++ b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/BgpDriverInfo.java
@@ -47,7 +47,7 @@
*
* @return model id level
*/
- BgpModelIdLevel modIdLevel() {
+ public BgpModelIdLevel modIdLevel() {
return modIdLevel;
}
@@ -56,8 +56,7 @@
*
* @return device id
*/
- String devId() {
+ public String devId() {
return devId;
}
-
}
diff --git a/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/BgpInfo.java b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/BgpInfo.java
index e461b24..8c21061 100644
--- a/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/BgpInfo.java
+++ b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/BgpInfo.java
@@ -46,7 +46,7 @@
*
* @return protocol info map.
*/
- Map<RouteProtocol, ProtocolInfo> protocolInfo() {
+ public Map<RouteProtocol, ProtocolInfo> protocolInfo() {
return protocolInfo;
}
@@ -55,7 +55,7 @@
*
* @param protocolInfo protocol info map
*/
- void protocolInfo(Map<RouteProtocol, ProtocolInfo> protocolInfo) {
+ public void protocolInfo(Map<RouteProtocol, ProtocolInfo> protocolInfo) {
this.protocolInfo = protocolInfo;
}
@@ -65,7 +65,7 @@
* @param route route protocol
* @param info protocol info
*/
- void addProtocolInfo(RouteProtocol route, ProtocolInfo info) {
+ public void addProtocolInfo(RouteProtocol route, ProtocolInfo info) {
if (protocolInfo == null) {
protocolInfo = new HashMap<>();
}
@@ -77,7 +77,7 @@
*
* @return VPN name
*/
- String vpnName() {
+ public String vpnName() {
return vpnName;
}
@@ -86,7 +86,7 @@
*
* @param vpnName VPN name
*/
- void vpnName(String vpnName) {
+ public void vpnName(String vpnName) {
this.vpnName = vpnName;
}
diff --git a/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/DeviceInfo.java b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/DeviceInfo.java
index 8b4421e..4198ee8 100644
--- a/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/DeviceInfo.java
+++ b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/DeviceInfo.java
@@ -63,7 +63,7 @@
*
* @return device id
*/
- DeviceId deviceId() {
+ public DeviceId deviceId() {
return deviceId;
}
@@ -72,7 +72,7 @@
*
* @param ifName interface name
*/
- void addIfName(String ifName) {
+ public void addIfName(String ifName) {
if (ifNames == null) {
ifNames = new LinkedList<>();
}
@@ -84,7 +84,7 @@
*
* @return interface names
*/
- List<String> ifNames() {
+ public List<String> ifNames() {
return ifNames;
}
@@ -93,7 +93,7 @@
*
* @param ifNames interface names
*/
- void ifNames(List<String> ifNames) {
+ public void ifNames(List<String> ifNames) {
this.ifNames = ifNames;
}
@@ -102,7 +102,7 @@
*
* @return BGP info
*/
- BgpInfo bgpInfo() {
+ public BgpInfo bgpInfo() {
return bgpInfo;
}
@@ -111,7 +111,7 @@
*
* @param bgpInfo BGP info
*/
- void bgpInfo(BgpInfo bgpInfo) {
+ public void bgpInfo(BgpInfo bgpInfo) {
this.bgpInfo = bgpInfo;
}
@@ -120,7 +120,7 @@
*
* @return network accesses
*/
- List<AccessInfo> accesses() {
+ public List<AccessInfo> accesses() {
return accesses;
}
@@ -129,7 +129,7 @@
*
* @param accesses network accesses
*/
- void accesses(List<AccessInfo> accesses) {
+ public void accesses(List<AccessInfo> accesses) {
this.accesses = accesses;
}
@@ -138,7 +138,7 @@
*
* @param accessInfo access info
*/
- void addAccessInfo(AccessInfo accessInfo) {
+ public void addAccessInfo(AccessInfo accessInfo) {
if (accesses == null) {
accesses = new LinkedList<>();
}
@@ -154,8 +154,8 @@
* @param modelData std device model object data
* @return driver instance model object data
*/
- ModelObjectData processCreateInstance(DriverService driverSvc,
- ModelObjectData modelData) {
+ public ModelObjectData processCreateInstance(DriverService driverSvc,
+ ModelObjectData modelData) {
// TODO: Need to call the behaviour.
return null;
}
@@ -169,8 +169,8 @@
* @param modData std device model object data
* @return driver interface model object data
*/
- ModelObjectData processCreateInterface(DriverService driverSvc,
- ModelObjectData modData) {
+ public ModelObjectData processCreateInterface(DriverService driverSvc,
+ ModelObjectData modData) {
// TODO: Need to call the behaviour.
return null;
}
@@ -185,9 +185,9 @@
* @param driverInfo driver config details
* @return driver BGP model object data
*/
- ModelObjectData processCreateBgpInfo(DriverService driverSvc,
- BgpInfo bgpInfo,
- BgpDriverInfo driverInfo) {
+ public ModelObjectData processCreateBgpInfo(DriverService driverSvc,
+ BgpInfo bgpInfo,
+ BgpDriverInfo driverInfo) {
// TODO: Need to call the behaviour.
return null;
}
@@ -201,7 +201,7 @@
* @param modData model object data
* @return driver instance model object data
*/
- ModelObjectData processDeleteInstance(DriverService driverSvc,
+ public ModelObjectData processDeleteInstance(DriverService driverSvc,
ModelObjectData modData) {
// TODO: Need to call the behaviour.
return null;
@@ -216,7 +216,7 @@
* @param objectData model object data
* @return driver interface model object data
*/
- ModelObjectData processDeleteInterface(DriverService driverSvc,
+ public ModelObjectData processDeleteInterface(DriverService driverSvc,
ModelObjectData objectData) {
// TODO: Need to call the behaviour.
return null;
@@ -232,7 +232,7 @@
* @param driverInfo driver config details
* @return driver BGP model object data
*/
- ModelObjectData processDeleteBgpInfo(DriverService driverSvc,
+ public ModelObjectData processDeleteBgpInfo(DriverService driverSvc,
BgpInfo bgpInfo,
BgpDriverInfo driverInfo) {
// TODO: Need to call the behaviour.
diff --git a/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/FullMeshVpnConfig.java b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/FullMeshVpnConfig.java
index 8802fc0..76bb756 100644
--- a/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/FullMeshVpnConfig.java
+++ b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/FullMeshVpnConfig.java
@@ -39,7 +39,7 @@
*
* @return RT value
*/
- String rt() {
+ public String rt() {
return rt;
}
}
diff --git a/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/HubSpokeVpnConfig.java b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/HubSpokeVpnConfig.java
index d305ae3..a2dfb96 100644
--- a/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/HubSpokeVpnConfig.java
+++ b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/HubSpokeVpnConfig.java
@@ -53,7 +53,7 @@
*
* @return RT value
*/
- String hubImpRt() {
+ public String hubImpRt() {
return hubImpRt;
}
@@ -62,7 +62,7 @@
*
* @param hubImpRt RT value
*/
- void hubImpRt(String hubImpRt) {
+ public void hubImpRt(String hubImpRt) {
this.hubImpRt = hubImpRt;
}
@@ -71,7 +71,7 @@
*
* @return RT value
*/
- String hubExpRt() {
+ public String hubExpRt() {
return hubExpRt;
}
@@ -80,7 +80,7 @@
*
* @param hubExpRt RT value
*/
- void hubExpRt(String hubExpRt) {
+ public void hubExpRt(String hubExpRt) {
this.hubExpRt = hubExpRt;
}
@@ -89,7 +89,7 @@
*
* @return RT value
*/
- String spokeImpRt() {
+ public String spokeImpRt() {
return spokeImpRt;
}
@@ -98,7 +98,7 @@
*
* @param spokeImpRt RT value
*/
- void spokeImpRt(String spokeImpRt) {
+ public void spokeImpRt(String spokeImpRt) {
this.spokeImpRt = spokeImpRt;
}
@@ -107,7 +107,7 @@
*
* @return RT value
*/
- String spokeExpRt() {
+ public String spokeExpRt() {
return spokeExpRt;
}
@@ -116,7 +116,7 @@
*
* @param spokeExpRt RT value
*/
- void spokeExpRt(String spokeExpRt) {
+ public void spokeExpRt(String spokeExpRt) {
this.spokeExpRt = spokeExpRt;
}
}
diff --git a/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/InterfaceInfo.java b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/InterfaceInfo.java
index ecdddb6..48b408a 100644
--- a/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/InterfaceInfo.java
+++ b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/InterfaceInfo.java
@@ -55,7 +55,7 @@
*
* @return device info
*/
- DeviceInfo devInfo() {
+ public DeviceInfo devInfo() {
return devInfo;
}
@@ -64,7 +64,7 @@
*
* @return interface name
*/
- String intName() {
+ public String intName() {
return intName;
}
@@ -73,7 +73,7 @@
*
* @return VPN name
*/
- String vpnName() {
+ public String vpnName() {
return vpnName;
}
}
diff --git a/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/ProtocolInfo.java b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/ProtocolInfo.java
index 1692127..1b873e7 100644
--- a/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/ProtocolInfo.java
+++ b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/ProtocolInfo.java
@@ -65,7 +65,7 @@
*
* @return route protocol
*/
- RouteProtocol routeProtocol() {
+ public RouteProtocol routeProtocol() {
return routeProtocol;
}
@@ -74,7 +74,7 @@
*
* @param routeProtocol route protocol
*/
- void routeProtocol(RouteProtocol routeProtocol) {
+ public void routeProtocol(RouteProtocol routeProtocol) {
this.routeProtocol = routeProtocol;
}
@@ -83,7 +83,7 @@
*
* @return process id
*/
- String processId() {
+ public String processId() {
return processId;
}
@@ -92,7 +92,7 @@
*
* @param processId process id.
*/
- void processId(String processId) {
+ public void processId(String processId) {
this.processId = processId;
}
@@ -102,7 +102,7 @@
*
* @return true if IPV4 address family uses; false otherwise
*/
- boolean isIpv4Af() {
+ public boolean isIpv4Af() {
return ipv4Af;
}
@@ -112,7 +112,7 @@
*
* @param ipv4Af true if IPV4 interface uses; false otherwise
*/
- void ipv4Af(boolean ipv4Af) {
+ public void ipv4Af(boolean ipv4Af) {
this.ipv4Af = ipv4Af;
}
@@ -122,7 +122,7 @@
*
* @return true if IPV6 address family uses; false otherwise
*/
- boolean isIpv6Af() {
+ public boolean isIpv6Af() {
return ipv6Af;
}
@@ -132,7 +132,7 @@
*
* @param ipv6Af true if IPV6 interface uses; false otherwise
*/
- void ipv6Af(boolean ipv6Af) {
+ public void ipv6Af(boolean ipv6Af) {
this.ipv6Af = ipv6Af;
}
@@ -141,7 +141,7 @@
*
* @return IPV4 network accesses
*/
- List<AccessInfo> v4Accesses() {
+ public List<AccessInfo> v4Accesses() {
return v4Accesses;
}
@@ -150,7 +150,7 @@
*
* @param v4Accesses IPV4 network accesses
*/
- void v4Accesses(List<AccessInfo> v4Accesses) {
+ public void v4Accesses(List<AccessInfo> v4Accesses) {
this.v4Accesses = v4Accesses;
}
@@ -159,7 +159,7 @@
*
* @param info IPV4 network access
*/
- void addV4Key(AccessInfo info) {
+ public void addV4Access(AccessInfo info) {
if (v4Accesses == null) {
v4Accesses = new LinkedList<>();
}
@@ -171,7 +171,7 @@
*
* @return IPV6 network accesses
*/
- List<AccessInfo> v6Accesses() {
+ public List<AccessInfo> v6Accesses() {
return v6Accesses;
}
@@ -180,7 +180,7 @@
*
* @param v6Accesses IPV6 network accesses
*/
- void v6Accesses(List<AccessInfo> v6Accesses) {
+ public void v6Accesses(List<AccessInfo> v6Accesses) {
this.v4Accesses = v6Accesses;
}
@@ -188,7 +188,7 @@
* Adds a access info to the IPV6 network accesses.
* @param info IPV4 network access
*/
- void addV6Key(AccessInfo info) {
+ public void addV6Access(AccessInfo info) {
if (v6Accesses == null) {
v6Accesses = new LinkedList<>();
}
diff --git a/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/RouteProtocol.java b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/RouteProtocol.java
index 8ff03f6..2bda454 100644
--- a/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/RouteProtocol.java
+++ b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/RouteProtocol.java
@@ -75,7 +75,7 @@
* @param name protocol name
* @return route protocol
*/
- static RouteProtocol getProType(String name) {
+ public static RouteProtocol getProType(String name) {
for (RouteProtocol protocol : values()) {
if (protocol.proType.equals(name.toLowerCase())) {
return protocol;
diff --git a/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/VpnConfig.java b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/VpnConfig.java
index d9973b0..0b39a43 100644
--- a/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/VpnConfig.java
+++ b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/VpnConfig.java
@@ -37,7 +37,7 @@
*
* @return RD value
*/
- String rd() {
+ public String rd() {
return rd;
}
@@ -46,7 +46,7 @@
*
* @param rd RD value
*/
- void rd(String rd) {
+ public void rd(String rd) {
this.rd = rd;
}
}
diff --git a/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/VpnInstance.java b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/VpnInstance.java
index b411b87..880ed51 100644
--- a/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/VpnInstance.java
+++ b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/VpnInstance.java
@@ -61,7 +61,7 @@
*
* @return VPN type
*/
- VpnType type() {
+ public VpnType type() {
return type;
}
@@ -70,7 +70,7 @@
*
* @param type VPN type
*/
- void type(VpnType type) {
+ public void type(VpnType type) {
this.type = type;
}
@@ -79,7 +79,7 @@
*
* @return VPN config
*/
- T vpnConfig() {
+ public T vpnConfig() {
return vpnConfig;
}
@@ -88,7 +88,7 @@
*
* @param vpnConfig VPN config
*/
- void vpnConfig(T vpnConfig) {
+ public void vpnConfig(T vpnConfig) {
this.vpnConfig = vpnConfig;
}
@@ -97,7 +97,7 @@
*
* @return device info map
*/
- Map<DeviceId, DeviceInfo> devInfo() {
+ public Map<DeviceId, DeviceInfo> devInfo() {
return devInfo;
}
@@ -106,7 +106,7 @@
*
* @param devInfo device info map
*/
- void devInfo(Map<DeviceId, DeviceInfo> devInfo) {
+ public void devInfo(Map<DeviceId, DeviceInfo> devInfo) {
this.devInfo = devInfo;
}
@@ -116,7 +116,7 @@
* @param id device id
* @param info device info
*/
- void devInfo(DeviceId id, DeviceInfo info) {
+ public void addDevInfo(DeviceId id, DeviceInfo info) {
if (devInfo == null) {
devInfo = new LinkedHashMap<>();
}
@@ -128,7 +128,7 @@
*
* @return VPN name
*/
- String vpnName() {
+ public String vpnName() {
return vpnName;
}
}
diff --git a/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/VpnSiteRole.java b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/VpnSiteRole.java
index e67018c..062fe56 100644
--- a/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/VpnSiteRole.java
+++ b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/VpnSiteRole.java
@@ -48,7 +48,7 @@
*
* @return VPN name
*/
- String name() {
+ public String name() {
return name;
}
@@ -57,7 +57,7 @@
*
* @return site role
*/
- VpnType role() {
+ public VpnType role() {
return role;
}
}
diff --git a/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/BgpConstructionUtil.java b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/BgpConstructionUtil.java
new file mode 100644
index 0000000..97ae129
--- /dev/null
+++ b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/BgpConstructionUtil.java
@@ -0,0 +1,244 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * 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.l3vpn.netl3vpn.AccessInfo;
+import org.onosproject.l3vpn.netl3vpn.BgpInfo;
+import org.onosproject.l3vpn.netl3vpn.DeviceInfo;
+import org.onosproject.l3vpn.netl3vpn.NetL3VpnException;
+import org.onosproject.l3vpn.netl3vpn.ProtocolInfo;
+import org.onosproject.l3vpn.netl3vpn.RouteProtocol;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.RoutingProtocolType;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.siteattachmentipconnection.IpConnection;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.siterouting.routingprotocols.RoutingProtocol;
+
+import java.util.List;
+import java.util.Map;
+
+import static org.onosproject.l3vpn.netl3vpn.RouteProtocol.DIRECT;
+import static org.onosproject.l3vpn.netl3vpn.RouteProtocol.STATIC;
+import static org.onosproject.l3vpn.netl3vpn.RouteProtocol.getProType;
+
+/**
+ * Representation of utility for BGP info creation and deletion.
+ */
+public final class BgpConstructionUtil {
+
+ private static final String ZERO = "0";
+
+ // No instantiation.
+ private BgpConstructionUtil() {
+ }
+
+ /**
+ * Creates the BGP info instance, from the routing protocols available.
+ * It returns BGP info if for the first time, else returns null.
+ *
+ * @param routes route protocol
+ * @param info device info
+ * @param vpnName VPN name
+ * @param connect ip connection
+ * @param access access info
+ * @return BGP info instance
+ */
+ public static BgpInfo createBgpInfo(List<RoutingProtocol> routes,
+ DeviceInfo info, String vpnName,
+ IpConnection connect, AccessInfo access) {
+ BgpInfo devBgp = info.bgpInfo();
+ BgpInfo infoBgp = new BgpInfo();
+ infoBgp.vpnName(vpnName);
+ if (devBgp != null) {
+ infoBgp = updateDevBgpInfo(devBgp, infoBgp, connect, routes, access);
+ } else {
+ infoBgp = updateDevBgpInfo(null, infoBgp, connect, routes, access);
+ info.bgpInfo(infoBgp);
+ }
+ if (infoBgp == null || infoBgp.protocolInfo() == null) {
+ return null;
+ }
+ return infoBgp;
+ }
+
+ /**
+ * Updates the device BGP info and also creates the BGP info which has to
+ * be sent to driver, if it is called for the first time.
+ *
+ * @param devBgp device BGP info
+ * @param driBgp driver BGP info
+ * @param connect ip connection
+ * @param routes route protocols
+ * @param access access info
+ * @return driver BGP info
+ */
+ private static BgpInfo updateDevBgpInfo(BgpInfo devBgp, BgpInfo driBgp,
+ IpConnection connect,
+ List<RoutingProtocol> routes,
+ AccessInfo access) {
+ for (RoutingProtocol route : routes) {
+ ProtocolInfo ifInfo = getRoutePro(route.type(), connect, access);
+ if (ifInfo != null) {
+ if (devBgp != null) {
+ ProtocolInfo info = addToDevBgp(ifInfo, devBgp, access);
+ ifInfo = getUpdatedProInfo(info, ifInfo);
+ }
+ if (ifInfo != null) {
+ driBgp.addProtocolInfo(ifInfo.routeProtocol(), ifInfo);
+ }
+ }
+ }
+ return driBgp;
+ }
+
+ /**
+ * Returns the updated protocol info that has to be sent to driver. If
+ * the protocol info is for the second time or more, the driver info's
+ * protocol info will not be sent. It will return null if no info is
+ * present or nothing to be sent to driver.
+ *
+ * @param devInfo device protocol info
+ * @param driInfo driver protocol info
+ * @return updated driver protocol info
+ */
+ private static ProtocolInfo getUpdatedProInfo(ProtocolInfo devInfo,
+ ProtocolInfo driInfo) {
+ if (driInfo.isIpv4Af() && driInfo.isIpv6Af()) {
+ if ((getV4Size(devInfo) > 1) && (getV6Size(devInfo) > 1)) {
+ return null;
+ }
+ if ((getV4Size(devInfo) > 1) && !(getV6Size(devInfo) > 1)) {
+ driInfo.ipv4Af(false);
+ } else if (!(getV4Size(devInfo) > 1) && (getV6Size(devInfo) > 1)) {
+ driInfo.ipv6Af(false);
+ }
+ }
+ if (driInfo.isIpv4Af() && !driInfo.isIpv6Af()) {
+ if (getV4Size(devInfo) > 1) {
+ return null;
+ }
+ }
+ if (!driInfo.isIpv4Af() && driInfo.isIpv6Af()) {
+ if (getV6Size(devInfo) > 1) {
+ return null;
+ }
+ }
+ return driInfo;
+ }
+
+ private static int getV4Size(ProtocolInfo proInfo) {
+ return proInfo.v4Accesses().size();
+ }
+
+ private static int getV6Size(ProtocolInfo proInfo) {
+ return proInfo.v6Accesses().size();
+ }
+
+ /**
+ * Adds the protocol info to the device BGP info.
+ *
+ * @param proInfo protocol info
+ * @param devBgp device BGP
+ * @param access access info
+ * @return protocol info
+ */
+ private static ProtocolInfo addToDevBgp(ProtocolInfo proInfo,
+ BgpInfo devBgp, AccessInfo access) {
+ Map<RouteProtocol, ProtocolInfo> devMap = devBgp.protocolInfo();
+ ProtocolInfo devInfo = devMap.get(proInfo.routeProtocol());
+ if (devInfo != null) {
+ if (proInfo.isIpv4Af()) {
+ devInfo.ipv4Af(proInfo.isIpv4Af());
+ devInfo.addV4Access(access);
+ }
+ if (proInfo.isIpv6Af()) {
+ devInfo.ipv6Af(proInfo.isIpv6Af());
+ devInfo.addV6Access(access);
+ }
+ } else {
+ devInfo = proInfo;
+ devBgp.addProtocolInfo(proInfo.routeProtocol(), devInfo);
+ }
+ return devInfo;
+ }
+
+
+ /**
+ * Returns the protocol info of BGP by taking values from the service files.
+ *
+ * @param type protocol type
+ * @param connect IP connection
+ * @param access access info
+ * @return protocol info
+ */
+ private static ProtocolInfo getRoutePro(Class<? extends RoutingProtocolType> type,
+ IpConnection connect, AccessInfo access) {
+ ProtocolInfo protocolInfo = new ProtocolInfo();
+ RouteProtocol protocol = getProType(type.getSimpleName());
+ switch (protocol) {
+ case DIRECT:
+ protocolInfo.routeProtocol(DIRECT);
+ protocolInfo.processId(ZERO);
+ setAddressFamily(protocolInfo, connect, access);
+ return protocolInfo;
+
+ case STATIC:
+ protocolInfo.routeProtocol(STATIC);
+ protocolInfo.processId(ZERO);
+ setAddressFamily(protocolInfo, connect, access);
+ return protocolInfo;
+
+ case BGP:
+ case OSPF:
+ case RIP:
+ case RIP_NG:
+ case VRRP:
+ default:
+ throw new NetL3VpnException(getRouteProErr(
+ type.getSimpleName()));
+ }
+ }
+
+ /**
+ * Returns the route protocol error message for unsupported type.
+ *
+ * @param type route protocol type
+ * @return error message
+ */
+ private static String getRouteProErr(String type) {
+ return type + " routing protocol is not supported.";
+ }
+
+ /**
+ * Sets the address family of the protocol info.
+ *
+ * @param proInfo protocol info
+ * @param connect ip connection
+ * @param access access info
+ */
+ private static void setAddressFamily(ProtocolInfo proInfo,
+ IpConnection connect, AccessInfo access) {
+ if (connect.ipv4() != null && connect.ipv4().addresses() != null &&
+ connect.ipv4().addresses().providerAddress() != null) {
+ proInfo.ipv4Af(true);
+ proInfo.addV4Access(access);
+ }
+ if (connect.ipv6() != null && connect.ipv6().addresses() != null &&
+ connect.ipv6().addresses().providerAddress() != null) {
+ proInfo.ipv6Af(true);
+ proInfo.addV6Access(access);
+ }
+ }
+}
diff --git a/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/InsConstructionUtil.java b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/InsConstructionUtil.java
new file mode 100644
index 0000000..d5ea1a6
--- /dev/null
+++ b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/InsConstructionUtil.java
@@ -0,0 +1,240 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * 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.l3vpn.netl3vpn.FullMeshVpnConfig;
+import org.onosproject.l3vpn.netl3vpn.HubSpokeVpnConfig;
+import org.onosproject.l3vpn.netl3vpn.VpnInstance;
+import org.onosproject.l3vpn.netl3vpn.VpnSiteRole;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.bgp.l3vpn.rev20160909.ietfbgpl3vpn.devices.device.networkinstances.networkinstance.AugmentedNiNetworkInstance;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.bgp.l3vpn.rev20160909.ietfbgpl3vpn.devices.device.networkinstances.networkinstance.DefaultAugmentedNiNetworkInstance;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.bgp.l3vpn.rev20160909.ietfbgpl3vpn.devices.device.networkinstances.networkinstance.augmentedninetworkinstance.DefaultL3Vpn;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.bgp.l3vpn.rev20160909.ietfbgpl3vpn.devices.device.networkinstances.networkinstance.augmentedninetworkinstance.L3Vpn;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.bgp.l3vpn.rev20160909.ietfbgpl3vpn.l3vpnvrfparams.DefaultIpv4;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.bgp.l3vpn.rev20160909.ietfbgpl3vpn.l3vpnvrfparams.DefaultIpv6;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.bgp.l3vpn.rev20160909.ietfbgpl3vpn.l3vpnvrfparams.Ipv4;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.bgp.l3vpn.rev20160909.ietfbgpl3vpn.l3vpnvrfparams.Ipv6;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.bgp.l3vpn.rev20160909.ietfbgpl3vpn.l3vpnvrfparams.ipv4.DefaultUnicast;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.bgp.l3vpn.rev20160909.ietfbgpl3vpn.l3vpnvrfparams.ipv4.Unicast;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.bgp.l3vpn.rev20160909.ietfbgpl3vpn.routedistinguisherparams.DefaultRouteDistinguisher;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.bgp.l3vpn.rev20160909.ietfbgpl3vpn.routedistinguisherparams.RouteDistinguisher;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.bgp.l3vpn.rev20160909.ietfbgpl3vpn.routetargetparams.DefaultRouteTargets;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.bgp.l3vpn.rev20160909.ietfbgpl3vpn.routetargetparams.RouteTargets;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.bgp.l3vpn.rev20160909.ietfbgpl3vpn.routetargetparams.routetargets.Config;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.bgp.l3vpn.rev20160909.ietfbgpl3vpn.routetargetparams.routetargets.DefaultConfig;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.bgp.l3vpn.rev20160909.ietfbgpl3vpn.routetargetset.DefaultRts;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.bgp.l3vpn.rev20160909.ietfbgpl3vpn.routetargetset.Rts;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.bgp.l3vpn.rev20160909.ietfbgpl3vpn.routetargetset.rts.RtTypeEnum;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.siteattachmentipconnection.IpConnection;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.instance.rev20160623.ietfnetworkinstance.devices.device.DefaultNetworkInstances;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.instance.rev20160623.ietfnetworkinstance.devices.device.NetworkInstances;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.instance.rev20160623.ietfnetworkinstance.devices.device.networkinstances.DefaultNetworkInstance;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.instance.rev20160623.ietfnetworkinstance.devices.device.networkinstances.NetworkInstance;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import static org.onosproject.l3vpn.netl3vpn.VpnType.ANY_TO_ANY;
+import static org.onosproject.l3vpn.netl3vpn.VpnType.HUB;
+import static org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.bgp.l3vpn.rev20160909.ietfbgpl3vpn.routetargetset.rts.RtTypeEnum.BOTH;
+import static org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.bgp.l3vpn.rev20160909.ietfbgpl3vpn.routetargetset.rts.RtTypeEnum.EXPORT;
+import static org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.bgp.l3vpn.rev20160909.ietfbgpl3vpn.routetargetset.rts.RtTypeEnum.IMPORT;
+
+/**
+ * Representation of utility for instance creation and deletion.
+ */
+public final class InsConstructionUtil {
+
+ // No instantiation.
+ private InsConstructionUtil() {
+ }
+
+ /**
+ * Creates network instance with augmented info such as RD and RT.
+ *
+ * @param vpnIns VPN instance
+ * @param role VPN role
+ * @param connect ip connection
+ * @return network instance
+ */
+ public static NetworkInstances createInstance(VpnInstance vpnIns,
+ VpnSiteRole role,
+ IpConnection connect) {
+ NetworkInstance ins = new DefaultNetworkInstance();
+ NetworkInstances instances = new DefaultNetworkInstances();
+ List<NetworkInstance> insList = new LinkedList<>();
+
+ L3Vpn l3Vpn = buildRd(vpnIns);
+ DefaultAugmentedNiNetworkInstance augIns =
+ buildRt(connect, role, l3Vpn, vpnIns);
+ ins.name(vpnIns.vpnName());
+ insList.add(ins);
+ ((DefaultNetworkInstance) ins).addAugmentation(augIns);
+ instances.networkInstance(insList);
+ return instances;
+ }
+
+ /**
+ * Builds RT from l3 VPN according to the address family VPN belongs to.
+ * It returns built aug network instance from l3 VPN.
+ *
+ * @param con ip connection
+ * @param role site VPN role
+ * @param l3Vpn l3 VPN
+ * @param ins VPN instance
+ * @return aug network instance
+ */
+ private static DefaultAugmentedNiNetworkInstance buildRt(IpConnection con,
+ VpnSiteRole role,
+ L3Vpn l3Vpn,
+ VpnInstance ins) {
+ Ipv4 ipv4 = null;
+ Ipv6 ipv6 = null;
+ if (con.ipv4() != null && con.ipv4().addresses()
+ .providerAddress() != null) {
+ ipv4 = buildIpv4Rt(role, ins);
+ }
+ if (con.ipv6() != null && con.ipv6()
+ .addresses().providerAddress() != null) {
+ ipv6 = buildIpv6Rt(role, ins);
+ }
+ l3Vpn.ipv4(ipv4);
+ l3Vpn.ipv6(ipv6);
+
+ AugmentedNiNetworkInstance augInst =
+ new DefaultAugmentedNiNetworkInstance();
+ augInst.l3Vpn(l3Vpn);
+ return (DefaultAugmentedNiNetworkInstance) augInst;
+ }
+
+ /**
+ * Builds ipv6 RT in the device model.
+ *
+ * @param role site VPN role
+ * @param vpnIns VPN instance
+ * @return ipv6
+ */
+ private static Ipv6 buildIpv6Rt(VpnSiteRole role, VpnInstance vpnIns) {
+ RouteTargets rts6 = new DefaultRouteTargets();
+ Ipv6 v6 = new DefaultIpv6();
+ org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.bgp.l3vpn
+ .rev20160909.ietfbgpl3vpn.l3vpnvrfparams.ipv6.Unicast uni6 =
+ new org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang
+ .ietf.bgp.l3vpn.rev20160909.ietfbgpl3vpn.l3vpnvrfparams
+ .ipv6.DefaultUnicast();
+
+ Config configV6 = configRouteTarget(vpnIns, role);
+ rts6.config(configV6);
+ uni6.routeTargets(rts6);
+ v6.unicast(uni6);
+ return v6;
+ }
+
+ /**
+ * Builds ipv4 RT in the device model.
+ *
+ * @param role site VPN role
+ * @param vpnIns VPN instance
+ * @return ipv4
+ */
+ private static Ipv4 buildIpv4Rt(VpnSiteRole role, VpnInstance vpnIns) {
+ RouteTargets rts4 = new DefaultRouteTargets();
+ Unicast uni4 = new DefaultUnicast();
+ Ipv4 v4 = new DefaultIpv4();
+
+ Config configV4 = configRouteTarget(vpnIns, role);
+ rts4.config(configV4);
+ uni4.routeTargets(rts4);
+ v4.unicast(uni4);
+ return v4;
+ }
+
+ /**
+ * Configures route target according to the site VPN role from the stored
+ * VPN instance.
+ *
+ * @param ins VPN instance
+ * @param role site VPN role
+ * @return route target config
+ */
+ private static Config configRouteTarget(VpnInstance ins,
+ VpnSiteRole role) {
+ Rts rts1;
+ Config config = new DefaultConfig();
+ List<Rts> rtsList = new LinkedList<>();
+
+ if (ins.type() == ANY_TO_ANY) {
+ String rtVal = ((FullMeshVpnConfig) ins.vpnConfig()).rt();
+ rts1 = getRtsVal(rtVal, BOTH);
+ } else {
+ String rtVal1;
+ String rtVal2;
+ HubSpokeVpnConfig conf = (HubSpokeVpnConfig) ins.vpnConfig();
+ if (role.role() == HUB) {
+ rtVal1 = conf.hubImpRt();
+ rtVal2 = conf.hubExpRt();
+ } else {
+ rtVal1 = conf.spokeImpRt();
+ rtVal2 = conf.spokeExpRt();
+ }
+ rts1 = getRtsVal(rtVal1, IMPORT);
+ Rts rts2 = getRtsVal(rtVal2, EXPORT);
+ rtsList.add(rts2);
+ }
+ rtsList.add(rts1);
+ config.rts(rtsList);
+ return config;
+ }
+
+ /**
+ * Returns the device model RT from the RT type and RT value after
+ * building it.
+ *
+ * @param rtVal RT value
+ * @param type RT type
+ * @return device model RT
+ */
+ private static Rts getRtsVal(String rtVal, RtTypeEnum type) {
+ Rts rts = new DefaultRts();
+ rts.rt(rtVal);
+ rts.rtType(type);
+ return rts;
+ }
+
+ /**
+ * Builds RD from the stored device model VPN instance.
+ *
+ * @param vpn VPN instance
+ * @return l3 VPN object
+ */
+ private static L3Vpn buildRd(VpnInstance vpn) {
+
+ String rd = vpn.vpnConfig().rd();
+ org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.bgp.l3vpn
+ .rev20160909.ietfbgpl3vpn.routedistinguisherparams
+ .routedistinguisher.Config config = new org.onosproject.yang
+ .gen.v1.urn.ietf.params.xml.ns.yang.ietf.bgp.l3vpn.rev20160909
+ .ietfbgpl3vpn.routedistinguisherparams.routedistinguisher
+ .DefaultConfig();
+ config.rd(rd);
+ RouteDistinguisher dist = new DefaultRouteDistinguisher();
+ dist.config(config);
+ L3Vpn l3vpn = new DefaultL3Vpn();
+ l3vpn.routeDistinguisher(dist);
+ return l3vpn;
+ }
+}
diff --git a/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/IntConstructionUtil.java b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/IntConstructionUtil.java
new file mode 100644
index 0000000..f087859
--- /dev/null
+++ b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/IntConstructionUtil.java
@@ -0,0 +1,199 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * 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.l3vpn.netl3vpn.NetL3VpnException;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev20130715.ietfinettypes.Ipv4Address;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev20130715.ietfinettypes.Ipv4AddressNoZone;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev20130715.ietfinettypes.Ipv6Address;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev20130715.ietfinettypes.Ipv6AddressNoZone;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev20140508.ietfinterfaces.devices.device.DefaultInterfaces;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev20140508.ietfinterfaces.devices.device.Interfaces;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev20140508.ietfinterfaces.devices.device.interfaces.DefaultYangAutoPrefixInterface;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev20140508.ietfinterfaces.devices.device.interfaces.YangAutoPrefixInterface;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev20140616.ietfip.devices.device.interfaces.yangautoprefixinterface.AugmentedIfInterface;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev20140616.ietfip.devices.device.interfaces.yangautoprefixinterface.DefaultAugmentedIfInterface;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev20140616.ietfip.devices.device.interfaces.yangautoprefixinterface.augmentedifinterface.DefaultIpv4;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev20140616.ietfip.devices.device.interfaces.yangautoprefixinterface.augmentedifinterface.DefaultIpv6;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev20140616.ietfip.devices.device.interfaces.yangautoprefixinterface.augmentedifinterface.Ipv4;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev20140616.ietfip.devices.device.interfaces.yangautoprefixinterface.augmentedifinterface.Ipv6;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev20140616.ietfip.devices.device.interfaces.yangautoprefixinterface.augmentedifinterface.ipv4.Address;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev20140616.ietfip.devices.device.interfaces.yangautoprefixinterface.augmentedifinterface.ipv4.DefaultAddress;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev20140616.ietfip.devices.device.interfaces.yangautoprefixinterface.augmentedifinterface.ipv4.address.Subnet;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev20140616.ietfip.devices.device.interfaces.yangautoprefixinterface.augmentedifinterface.ipv4.address.subnet.DefaultPrefixLength;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.siteattachmentipconnection.IpConnection;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.instance.rev20160623.ietfnetworkinstance.devices.device.interfaces.yangautoprefixinterface.ipv4.AugmentedIpIpv4;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.instance.rev20160623.ietfnetworkinstance.devices.device.interfaces.yangautoprefixinterface.ipv4.DefaultAugmentedIpIpv4;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.instance.rev20160623.ietfnetworkinstance.devices.device.interfaces.yangautoprefixinterface.ipv6.AugmentedIpIpv6;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.instance.rev20160623.ietfnetworkinstance.devices.device.interfaces.yangautoprefixinterface.ipv6.DefaultAugmentedIpIpv6;
+import org.onosproject.yang.model.InnerModelObject;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Representation of utility for interface creation and deletion.
+ */
+public final class IntConstructionUtil {
+
+ private static final String IP_ADD_NULL = "Vpn binding to an interface " +
+ "requires ip address.";
+
+ // No instantiation.
+ private IntConstructionUtil() {
+ }
+
+ /**
+ * Creates device model interface by building its parameters with port
+ * name, VPN name and ip connection.
+ *
+ * @param pName port name
+ * @param vpnName VPN name
+ * @param connect ip connection
+ * @return interface device model
+ */
+ public static Interfaces createInterface(String pName, String vpnName,
+ IpConnection connect) {
+ Interfaces interfaces = new DefaultInterfaces();
+ List<YangAutoPrefixInterface> intList = new LinkedList<>();
+ YangAutoPrefixInterface inter = buildInterface(vpnName, pName, connect);
+ intList.add(inter);
+ interfaces.yangAutoPrefixInterface(intList);
+ return interfaces;
+ }
+
+ /**
+ * Builds augmented info of ip address to the interface.
+ *
+ * @param vpnName VPN name
+ * @param pName port name
+ * @param connect ip connection
+ * @return interface
+ */
+ private static YangAutoPrefixInterface buildInterface(String vpnName,
+ String pName,
+ IpConnection connect) {
+ // Bind vpn name in the augmented info of interface.
+ org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network
+ .instance.rev20160623.ietfnetworkinstance.devices.device
+ .interfaces.yangautoprefixinterface.AugmentedIfInterface augIf =
+ new org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang
+ .ietf.network.instance.rev20160623.ietfnetworkinstance
+ .devices.device.interfaces.yangautoprefixinterface
+ .DefaultAugmentedIfInterface();
+ augIf.bindNetworkInstanceName(vpnName);
+
+ // Bind ip address to the interface as augmented info.
+ AugmentedIfInterface intAug = buildIpAddress(connect, vpnName);
+ YangAutoPrefixInterface inter = new DefaultYangAutoPrefixInterface();
+ inter.name(pName);
+ ((DefaultYangAutoPrefixInterface) inter).addAugmentation(
+ (InnerModelObject) augIf);
+ ((DefaultYangAutoPrefixInterface) inter).addAugmentation(
+ (InnerModelObject) intAug);
+
+ return inter;
+ }
+
+ /**
+ * Returns ipv6 address filled with attached VPN, ipv6 address and mask.
+ *
+ * @param vpnName VPN name
+ * @param mask mask
+ * @param ipv6Add ipv6 address
+ * @return device ipv6 address
+ */
+ private static Ipv6 getIpv6Aug(String vpnName, short mask, String ipv6Add) {
+ AugmentedIpIpv6 augIpv6 = new DefaultAugmentedIpIpv6();
+ org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip
+ .rev20140616.ietfip.devices.device.interfaces
+ .yangautoprefixinterface.augmentedifinterface.ipv6.Address add =
+ new org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
+ .ip.rev20140616.ietfip.devices.device.interfaces
+ .yangautoprefixinterface.augmentedifinterface.ipv6
+ .DefaultAddress();
+ Ipv6 ipv6 = new DefaultIpv6();
+ List<org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip
+ .rev20140616.ietfip.devices.device.interfaces
+ .yangautoprefixinterface.augmentedifinterface.ipv6
+ .Address> addList = new LinkedList<>();
+ add.ip(Ipv6AddressNoZone.of(Ipv6Address.of(ipv6Add)));
+ augIpv6.bindNetworkInstanceName(vpnName);
+ add.prefixLength(mask);
+ addList.add(add);
+ ipv6.address(addList);
+ ((DefaultIpv6) ipv6).addAugmentation((DefaultAugmentedIpIpv6) augIpv6);
+ return ipv6;
+ }
+
+ /**
+ * Returns ipv4 address filled with attached VPN, ipv4 address and mask.
+ *
+ * @param vpnName VPN name
+ * @param mask mask
+ * @param ipv4Add ipv4 address
+ * @return device ipv4 address
+ */
+ private static Ipv4 getIpv4Aug(String vpnName, short mask, String ipv4Add) {
+ AugmentedIpIpv4 augIpv4 = new DefaultAugmentedIpIpv4();
+ Subnet net = new DefaultPrefixLength();
+ Address add = new DefaultAddress();
+ Ipv4 ipv4 = new DefaultIpv4();
+ List<Address> addList = new LinkedList<>();
+
+ augIpv4.bindNetworkInstanceName(vpnName);
+ ((DefaultPrefixLength) net).prefixLength(mask);
+ add.ip(Ipv4AddressNoZone.of(Ipv4Address.of(ipv4Add)));
+ add.subnet(net);
+ addList.add(add);
+ ipv4.address(addList);
+ ((DefaultIpv4) ipv4).addAugmentation((DefaultAugmentedIpIpv4) augIpv4);
+ return ipv4;
+ }
+
+ /**
+ * Builds ip address according to the existence of ip address in ip
+ * connection of device model.
+ *
+ * @param connect ip connection
+ * @param vpnName VPN name
+ * @return augmented interface
+ */
+ public static AugmentedIfInterface buildIpAddress(IpConnection connect,
+ String vpnName) {
+ if (connect == null || (connect.ipv4() == null
+ && connect.ipv6() == null)) {
+ throw new NetL3VpnException(IP_ADD_NULL);
+ }
+ AugmentedIfInterface intAug = new DefaultAugmentedIfInterface();
+ short mask;
+ if (connect.ipv4() != null) {
+ mask = connect.ipv4().addresses().mask();
+ Ipv4Address peIpv4 = connect.ipv4().addresses().providerAddress();
+ Ipv4 v4 = getIpv4Aug(vpnName, mask, peIpv4.string());
+ intAug.ipv4(v4);
+ }
+
+ if (connect.ipv6() != null) {
+ mask = connect.ipv6().addresses().mask();
+ Ipv6Address peIpv6 = connect.ipv6().addresses().providerAddress();
+ Ipv6 v6 = getIpv6Aug(vpnName, mask, peIpv6.string());
+ intAug.ipv6(v6);
+ }
+ return intAug;
+ }
+}
diff --git a/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/NetL3VpnUtil.java b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/NetL3VpnUtil.java
new file mode 100644
index 0000000..11674e4
--- /dev/null
+++ b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/NetL3VpnUtil.java
@@ -0,0 +1,451 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * 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.l3vpn.netl3vpn.AccessInfo;
+import org.onosproject.l3vpn.netl3vpn.BgpDriverInfo;
+import org.onosproject.l3vpn.netl3vpn.BgpInfo;
+import org.onosproject.l3vpn.netl3vpn.InterfaceInfo;
+import org.onosproject.l3vpn.netl3vpn.NetL3VpnException;
+import org.onosproject.l3vpn.netl3vpn.VpnType;
+import org.onosproject.net.DeviceId;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev20140508.ietfinterfaces.devices.device.Interfaces;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.DefaultL3VpnSvc;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.SiteRole;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.l3vpnsvc.DefaultSites;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.instance.rev20160623.ietfnetworkinstance.DefaultDevices;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.instance.rev20160623.ietfnetworkinstance.Devices;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.instance.rev20160623.ietfnetworkinstance.devices.DefaultDevice;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.instance.rev20160623.ietfnetworkinstance.devices.Device;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.instance.rev20160623.ietfnetworkinstance.devices.DeviceKeys;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.instance.rev20160623.ietfnetworkinstance.devices.device.NetworkInstances;
+import org.onosproject.yang.model.DataNode;
+import org.onosproject.yang.model.DefaultModelObjectData;
+import org.onosproject.yang.model.InnerModelObject;
+import org.onosproject.yang.model.ModelObjectData;
+import org.onosproject.yang.model.ModelObjectId;
+import org.onosproject.yang.model.ResourceData;
+import org.onosproject.yang.model.ResourceId;
+import org.onosproject.yang.runtime.DefaultResourceData;
+
+import java.util.LinkedList;
+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.VpnType.ANY_TO_ANY;
+import static org.onosproject.l3vpn.netl3vpn.VpnType.HUB;
+import static org.onosproject.l3vpn.netl3vpn.VpnType.SPOKE;
+
+/**
+ * Representation of utility for YANG tree builder.
+ */
+public final class NetL3VpnUtil {
+
+ /**
+ * Error message for unsupported event from config store.
+ */
+ static final String EVENT_NOT_SUPPORTED = "Unsupported config event has " +
+ "come";
+
+ /**
+ * Error message for site VPN name being not present in global VPN.
+ */
+ static final String SITE_VPN_MISMATCH = "Site VPN instance name did not " +
+ "match any of the global VPN names";
+
+ /**
+ * Error message for VPN attachment object being null.
+ */
+ static final String VPN_ATTACHMENT_NULL = "The VPN attachment information" +
+ " cannot be null";
+
+ /**
+ * Error message for VPN policy being not supported.
+ */
+ static final String VPN_POLICY_NOT_SUPPORTED = "VPN policy implementation" +
+ " is not supported.";
+
+ /**
+ * Static constant value for hundred.
+ */
+ static final String CONS_HUNDRED = "100:";
+
+ /**
+ * Error message for site role being not present in site network access.
+ */
+ static final String SITE_ROLE_NULL = "There must be a site role available" +
+ " for the VPN in site network access.";
+
+ /**
+ * Error message for bearer object information being null.
+ */
+ static final String BEARER_NULL = "The bearer information of the access " +
+ "is not available";
+
+ /**
+ * Error message for requested type or ip connect being null.
+ */
+ static final String IP_INT_INFO_NULL = "The required information of " +
+ "request type or ip connection is not available";
+
+ /**
+ * Error message for device info being not available from augment.
+ */
+ static final String DEVICE_INFO_NULL = "Bearer of site does not have any " +
+ "device information in the augment info.";
+
+ /**
+ * Static constant value for management address.
+ */
+ static final String MG_MT_ADD = "managementAddress";
+
+ /**
+ * Error message for VPN type being not supported.
+ */
+ static final String VPN_TYPE_UNSUPPORTED = "The VPN type is not supported";
+
+ /**
+ * Error message when the generated ID has crossed the limit.
+ */
+ static final String ID_LIMIT_EXCEEDED = "The ID generation has got " +
+ "exceeded";
+
+ /**
+ * Static constant value ID management limit.
+ */
+ static final Long ID_LIMIT = 4294967295L;
+
+ /**
+ * Error message for interface information being not available.
+ */
+ static final String INT_INFO_NULL = "Requested type does not have any " +
+ "interface information in the augment info.";
+
+ /**
+ * Static constant value of port name.
+ */
+ static final String PORT_NAME = "portName";
+
+ 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";
+
+ // No instantiation.
+ private NetL3VpnUtil() {
+ }
+
+ /**
+ * Returns the model object id for service L3VPN container.
+ *
+ * @return model object id
+ */
+ static ModelObjectId getModIdForL3VpnSvc() {
+ return ModelObjectId.builder().addChild(DefaultL3VpnSvc.class).build();
+ }
+
+ /**
+ * Returns the model object id for service sites container.
+ *
+ * @return model object id
+ */
+ static ModelObjectId getModIdForSites() {
+ return ModelObjectId.builder().addChild(DefaultL3VpnSvc.class)
+ .addChild(DefaultSites.class).build();
+ }
+
+ /**
+ * Returns the resource data from the data node and the resource id.
+ *
+ * @param dataNode data node
+ * @param resId resource id
+ * @return resource data
+ */
+ static ResourceData getResourceData(DataNode dataNode, ResourceId resId) {
+ return DefaultResourceData.builder().addDataNode(dataNode)
+ .resourceId(resId).build();
+ }
+
+ /**
+ * Returns the VPN role from the service site role.
+ *
+ * @param siteRole service site role
+ * @return VPN type
+ */
+ static VpnType getRole(Class<? extends SiteRole> siteRole) {
+ switch (siteRole.getSimpleName()) {
+ case ANY_TO_ANY_ROLE:
+ return ANY_TO_ANY;
+
+ case HUB_ROLE:
+ return HUB;
+
+ case SPOKE_ROLE:
+ return SPOKE;
+
+ default:
+ throw new NetL3VpnException(SITE_ROLE_INVALID);
+ }
+ }
+
+ /**
+ * Returns error message for management ip being unavailable in device.
+ *
+ * @param ip management ip
+ * @return error message
+ */
+ static String getMgmtIpUnAvailErr(String ip) {
+ return "The device with management ip " + ip + " is not available.";
+ }
+
+ /**
+ * Returns true if device id present in the interface map; false otherwise.
+ *
+ * @param info interface map
+ * @param id device id
+ * @return true if device id available; false otherwise
+ */
+ private static boolean isDevIdPresent(Map<AccessInfo, InterfaceInfo> info,
+ String id) {
+ for (Map.Entry<AccessInfo, InterfaceInfo> inter : info.entrySet()) {
+ InterfaceInfo interfaceInfo = inter.getValue();
+ DeviceId devId = interfaceInfo.devInfo().deviceId();
+ if (devId.toString().equals(id)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Builds the device model VPN instance model object data, with respect to
+ * the device level.
+ *
+ * @param id device id
+ * @param ins VPN instance
+ * @return model object data, with device level
+ */
+ private static ModelObjectData buildInsModDataDevice(String id,
+ NetworkInstances ins) {
+ DeviceKeys devKeys = new DeviceKeys();
+ devKeys.deviceid(id);
+ ModelObjectId modelId = ModelObjectId.builder()
+ .addChild(DefaultDevices.class)
+ .addChild(DefaultDevice.class, devKeys)
+ .build();
+ return DefaultModelObjectData.builder().identifer(modelId)
+ .addModelObject((InnerModelObject) ins).build();
+ }
+
+ /**
+ * Builds the device model VPN instance model object data, with respect to
+ * the devices level.
+ *
+ * @param id device id
+ * @param ins VPN instance
+ * @return model object data, with devices level
+ */
+ private static ModelObjectData buildInsModDataDevices(String id,
+ NetworkInstances ins) {
+ ModelObjectId modelId = ModelObjectId.builder()
+ .addChild(DefaultDevices.class).build();
+ Device device = new DefaultDevice();
+ device.deviceid(id);
+ device.networkInstances(ins);
+ return DefaultModelObjectData.builder().identifer(modelId)
+ .addModelObject((InnerModelObject) device).build();
+ }
+
+ /**
+ * Builds the device model VPN instance model object data, with respect to
+ * root level.
+ *
+ * @param id device id
+ * @param ins VPN instance
+ * @return model object data, with root level
+ */
+ private static ModelObjectData buildInsModDataRoot(String id,
+ NetworkInstances ins) {
+ Devices devices = new DefaultDevices();
+ Device device = new DefaultDevice();
+ List<Device> deviceList = new LinkedList<>();
+ device.deviceid(id);
+ device.networkInstances(ins);
+ deviceList.add(device);
+ devices.device(deviceList);
+ return DefaultModelObjectData.builder()
+ .addModelObject((InnerModelObject) devices).build();
+ }
+
+ /**
+ * Builds the device model interface model object data, with respect to
+ * device level.
+ *
+ * @param id device id
+ * @param ifs interface object
+ * @return model object data, with device level
+ */
+ private static ModelObjectData buildIntModDataDevice(String id,
+ Interfaces ifs) {
+ org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces
+ .rev20140508.ietfinterfaces.devices.DeviceKeys keys =
+ new org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang
+ .ietf.interfaces.rev20140508.ietfinterfaces.devices
+ .DeviceKeys();
+ keys.deviceid(id);
+ ModelObjectId modelId = ModelObjectId.builder()
+ .addChild(org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns
+ .yang.ietf.interfaces.rev20140508
+ .ietfinterfaces.DefaultDevices.class)
+ .addChild(org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns
+ .yang.ietf.interfaces.rev20140508
+ .ietfinterfaces.devices.DefaultDevice.class,
+ keys)
+ .build();
+ return DefaultModelObjectData.builder().identifer(modelId)
+ .addModelObject((InnerModelObject) ifs).build();
+ }
+
+ /**
+ * Returns the VPN instance create model object data.
+ *
+ * @param intMap interface map
+ * @param instances VPN instances
+ * @param id device id
+ * @return VPN instance model object data
+ */
+ static ModelObjectData getVpnCreateModObj(Map<AccessInfo, InterfaceInfo> intMap,
+ NetworkInstances instances,
+ String id) {
+ ModelObjectData modData;
+ boolean devAdded = isDevIdPresent(intMap, id);
+ if (devAdded) {
+ modData = buildInsModDataDevice(id, instances);
+ } else if (intMap.size() != 0) {
+ modData = buildInsModDataDevices(id, instances);
+ } else {
+ modData = buildInsModDataRoot(id, instances);
+ }
+ return modData;
+ }
+
+ /**
+ * Returns error message for interface being unavailable in device.
+ *
+ * @param intName interface name
+ * @return error message
+ */
+ static String getIntNotAvailable(String intName) {
+ return "The interface " + intName + " is not available.";
+ }
+
+ /**
+ * Returns the interface create model object data.
+ *
+ * @param intMap interface map
+ * @param ifs interface instance
+ * @param id device id
+ * @return interface model object data
+ */
+ static ModelObjectData getIntCreateModObj(Map<AccessInfo, InterfaceInfo> intMap,
+ Interfaces ifs, String id) {
+ ModelObjectData modData;
+ boolean intAdded = isDevIdPresent(intMap, id);
+ if (intAdded) {
+ modData = buildIntModDataDevice(id, ifs);
+ } else {
+ modData = buildIntModDataRoot(id, ifs);
+ }
+ return modData;
+ }
+
+ /**
+ * Builds the device model interface model object data, with respect to
+ * root level.
+ *
+ * @param id device id
+ * @param ifs interface object
+ * @return model object data, with root level
+ */
+ private static ModelObjectData buildIntModDataRoot(String id,
+ Interfaces ifs) {
+ org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces
+ .rev20140508.ietfinterfaces.Devices devices =
+ new org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang
+ .ietf.interfaces.rev20140508.ietfinterfaces
+ .DefaultDevices();
+ org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces
+ .rev20140508.ietfinterfaces.devices.Device device =
+ new org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang
+ .ietf.interfaces.rev20140508.ietfinterfaces.devices
+ .DefaultDevice();
+ List<org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
+ .interfaces.rev20140508.ietfinterfaces.devices
+ .Device> deviceList = new LinkedList<>();
+
+ device.deviceid(id);
+ device.interfaces(ifs);
+ deviceList.add(device);
+ devices.device(deviceList);
+ return DefaultModelObjectData.builder()
+ .addModelObject((InnerModelObject) devices).build();
+ }
+
+ /**
+ * Returns the BGP create driver info.
+ *
+ * @param bgpMap BGP map
+ * @param id device id
+ * @return driver config info
+ */
+ static BgpDriverInfo getBgpCreateConfigObj(Map<BgpInfo, DeviceId> bgpMap,
+ String id) {
+ boolean isDevIdPresent = isDevIdBgpPresent(bgpMap, id);
+ BgpDriverInfo info;
+ if (isDevIdPresent) {
+ info = new BgpDriverInfo(DEVICE, id);
+
+ } else if (bgpMap.size() != 0) {
+ info = new BgpDriverInfo(DEVICES, id);
+ } else {
+ info = new BgpDriverInfo(ROOT, id);
+ }
+ return info;
+ }
+
+ /**
+ * Returns true if the device is present in the BGP map; false otherwise.
+ *
+ * @param bgpMap BGP map
+ * @param id device id
+ * @return true if device is present; false otherwise
+ */
+ private static boolean isDevIdBgpPresent(Map<BgpInfo, DeviceId> bgpMap,
+ String id) {
+ for (Map.Entry<BgpInfo, DeviceId> info : bgpMap.entrySet()) {
+ DeviceId devId = info.getValue();
+ if (devId.toString().equals(id)) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/NetL3vpnManager.java b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/NetL3vpnManager.java
index 107440c..4ccf0a1 100644
--- a/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/NetL3vpnManager.java
+++ b/apps/l3vpn/netl3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/impl/NetL3vpnManager.java
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.onosproject.l3vpn.netl3vpn.impl;
import org.apache.felix.scr.annotations.Activate;
@@ -21,11 +20,67 @@
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onosproject.config.DynamicConfigEvent;
+import org.onosproject.config.DynamicConfigListener;
+import org.onosproject.config.DynamicConfigService;
import org.onosproject.core.CoreService;
+import org.onosproject.core.IdGenerator;
+import org.onosproject.l3vpn.netl3vpn.AccessInfo;
+import org.onosproject.l3vpn.netl3vpn.BgpDriverInfo;
+import org.onosproject.l3vpn.netl3vpn.BgpInfo;
+import org.onosproject.l3vpn.netl3vpn.DeviceInfo;
+import org.onosproject.l3vpn.netl3vpn.FullMeshVpnConfig;
+import org.onosproject.l3vpn.netl3vpn.HubSpokeVpnConfig;
+import org.onosproject.l3vpn.netl3vpn.InterfaceInfo;
+import org.onosproject.l3vpn.netl3vpn.NetL3VpnException;
+import org.onosproject.l3vpn.netl3vpn.NetL3VpnStore;
+import org.onosproject.l3vpn.netl3vpn.VpnConfig;
+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.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev20130715.IetfInetTypes;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev20140508.ietfinterfaces.devices.device.Interfaces;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.IetfL3VpnSvc;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.DefaultL3VpnSvc;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.L3VpnSvc;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.accessvpnpolicy.VpnAttachment;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.accessvpnpolicy.vpnattachment.AttachmentFlavor;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.accessvpnpolicy.vpnattachment.attachmentflavor.DefaultVpnId;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.l3vpnsvc.Sites;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.l3vpnsvc.VpnServices;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.l3vpnsvc.sites.Site;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.l3vpnsvc.sites.site.SiteNetworkAccesses;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.l3vpnsvc.sites.site.sitenetworkaccesses.SiteNetworkAccess;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.l3vpnsvc.vpnservices.VpnSvc;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.siteattachmentbearer.Bearer;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.siteattachmentbearer.DefaultBearer;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.siteattachmentbearer.bearer.DefaultRequestedType;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.siteattachmentbearer.bearer.RequestedType;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.siteattachmentipconnection.IpConnection;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.siterouting.RoutingProtocols;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.l3vpn.svc.rev20160730.ietfl3vpnsvc.siterouting.routingprotocols.RoutingProtocol;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.instance.rev20160623.ietfnetworkinstance.devices.device.NetworkInstances;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev20130715.IetfYangTypes;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.l3vpn.svc.ext.rev20160730.L3VpnSvcExt;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.l3vpn.svc.ext.rev20160730.l3vpnsvcext.l3vpnsvc.sites.site.sitenetworkaccesses.sitenetworkaccess.bearer.DefaultAugmentedL3VpnBearer;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.l3vpn.svc.ext.rev20160730.l3vpnsvcext.l3vpnsvc.sites.site.sitenetworkaccesses.sitenetworkaccess.bearer.requestedtype.DefaultAugmentedL3VpnRequestedType;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.l3vpn.svc.ext.rev20160730.l3vpnsvcext.requestedtypegrouping.requestedtypeprofile.RequestedTypeChoice;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.l3vpn.svc.ext.rev20160730.l3vpnsvcext.requestedtypegrouping.requestedtypeprofile.requestedtypechoice.DefaultDot1Qcase;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.l3vpn.svc.ext.rev20160730.l3vpnsvcext.requestedtypegrouping.requestedtypeprofile.requestedtypechoice.DefaultPhysicalCase;
+import org.onosproject.yang.model.DataNode;
+import org.onosproject.yang.model.DefaultModelObjectData;
+import org.onosproject.yang.model.ModelConverter;
+import org.onosproject.yang.model.ModelObject;
+import org.onosproject.yang.model.ModelObjectData;
+import org.onosproject.yang.model.ModelObjectId;
+import org.onosproject.yang.model.NodeKey;
+import org.onosproject.yang.model.ResourceData;
+import org.onosproject.yang.model.ResourceId;
import org.onosproject.yang.model.YangModel;
import org.onosproject.yang.model.YangModuleId;
import org.onosproject.yang.runtime.DefaultAppModuleInfo;
@@ -36,7 +91,42 @@
import org.slf4j.LoggerFactory;
import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.config.DynamicConfigEvent.Type.NODE_ADDED;
+import static org.onosproject.config.DynamicConfigEvent.Type.NODE_DELETED;
+import static org.onosproject.l3vpn.netl3vpn.impl.BgpConstructionUtil.createBgpInfo;
+import static org.onosproject.l3vpn.netl3vpn.impl.InsConstructionUtil.createInstance;
+import static org.onosproject.l3vpn.netl3vpn.impl.IntConstructionUtil.createInterface;
+import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.BEARER_NULL;
+import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.CONS_HUNDRED;
+import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.DEVICE_INFO_NULL;
+import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.EVENT_NOT_SUPPORTED;
+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_INT_INFO_NULL;
+import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.MG_MT_ADD;
+import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.PORT_NAME;
+import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.SITE_ROLE_NULL;
+import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.SITE_VPN_MISMATCH;
+import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.VPN_ATTACHMENT_NULL;
+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.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;
+import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getRole;
+import static org.onosproject.l3vpn.netl3vpn.impl.NetL3VpnUtil.getVpnCreateModObj;
+import static org.onosproject.l3vpn.netl3vpn.VpnType.HUB;
import static org.onosproject.yang.runtime.helperutils.YangApacheUtils.getYangModel;
/**
@@ -47,26 +137,60 @@
public class NetL3vpnManager {
private static final String APP_ID = "org.onosproject.app.l3vpn";
+ private static final String L3_VPN_ID_TOPIC = "l3vpn-id";
+ private static final String ONOS_NET_L3VPN = "onos/netl3vpn";
+ private static final String EVENT_HANDLER = "event-handler-%d";
+
private final Logger log = LoggerFactory.getLogger(getClass());
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreService coreService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected DriverService driverService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected DeviceService deviceService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected YangModelRegistry modelRegistry;
- private ModelRegistrationParam regParam = null;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected ModelConverter modelConverter;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected DynamicConfigService configService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected NetL3VpnStore l3VpnStore;
+
+ protected IdGenerator l3VpnIdGen;
+
+ private DynamicConfigListener configListener = new InternalConfigListener();
+
+ private ModelRegistrationParam regParam;
+
+ private ExecutorService executor = Executors.newSingleThreadExecutor(
+ groupedThreads(ONOS_NET_L3VPN, EVENT_HANDLER, log));
+
+ private ResourceId id;
+ private ResourceId module;
+ private ResourceId sites;
@Activate
protected void activate() {
coreService.registerApplication(APP_ID);
+ l3VpnIdGen = coreService.getIdGenerator(L3_VPN_ID_TOPIC);
+ registerModel();
+ getResourceId();
+ configService.addListener(configListener);
log.info("Started");
- //TODO implementation
}
@Deactivate
protected void deactivate() {
modelRegistry.unregisterModel(regParam);
+ configService.removeListener(configListener);
log.info("Stopped");
}
@@ -105,4 +229,638 @@
regParam = b.build();
modelRegistry.registerModel(regParam);
}
+
+ /**
+ * Returns id as string. If the id is not in the freed list a new id is
+ * generated else the id from the freed list is used.
+ *
+ * @return id
+ */
+ private String getIdFromGen() {
+ Long value;
+ Iterable<Long> freeIds = l3VpnStore.getFreedIdList();
+ Iterator<Long> it = freeIds.iterator();
+ if (it.hasNext()) {
+ value = it.next();
+ l3VpnStore.removeIdFromFreeList(value);
+ } else {
+ value = l3VpnIdGen.getNewId();
+ }
+ if (value > ID_LIMIT) {
+ throw new RuntimeException(ID_LIMIT_EXCEEDED);
+ }
+ return CONS_HUNDRED + String.valueOf(value);
+ }
+
+ /**
+ * Returns the resource id, after constructing model object id and
+ * converting it.
+ */
+ private void getResourceId() {
+
+ ModelObjectId moduleId = ModelObjectId.builder().build();
+ module = getResourceVal(moduleId);
+
+ ModelObjectId svcId = getModIdForL3VpnSvc();
+ id = getResourceVal(svcId);
+
+ ModelObjectId sitesId = getModIdForSites();
+ sites = getResourceVal(sitesId);
+ }
+
+ /**
+ * Returns resource id from model converter.
+ *
+ * @param modelId model object id
+ * @return resource id
+ */
+ private ResourceId getResourceVal(ModelObjectId modelId) {
+ DefaultModelObjectData.Builder data = DefaultModelObjectData.builder()
+ .identifer(modelId);
+ ResourceData resData = modelConverter.createDataNode(data.build());
+ return resData.resourceId();
+ }
+
+ /**
+ * Processes create request from the store, by taking the root object.
+ * The root object is then used for l3VPN processing.
+ *
+ * @param storeId store resource id
+ */
+ private void processCreateFromStore(ResourceId storeId) {
+ List<ModelObject> objects = getModelObjects(storeId, module);
+ for (ModelObject obj : objects) {
+ if (obj instanceof DefaultL3VpnSvc) {
+ DefaultL3VpnSvc l3VpnSvc = (DefaultL3VpnSvc) obj;
+ createGlobalConfig(l3VpnSvc);
+ }
+ }
+ }
+
+ /**
+ * Returns model objects of the store. The data node is read from the
+ * config store. This returns the resource id's node. So the node's
+ * parent resource id is taken and the data node is given to model
+ * converter.
+ *
+ * @param storeId store resource id
+ * @param appId parent resource id
+ * @return model objects
+ */
+ public List<ModelObject> getModelObjects(ResourceId storeId,
+ ResourceId appId) {
+ DataNode dataNode = configService.readNode(storeId, null);
+ ResourceData data = getResourceData(dataNode, appId);
+ ModelObjectData modelData = modelConverter.createModel(data);
+ return modelData.modelObjects();
+ }
+
+ /**
+ * Returns true if the event resource id points to the root level node
+ * only and event is for addition and deletion; false otherwise.
+ *
+ * @param event config event
+ * @return true if event is supported; false otherwise
+ */
+ public boolean isSupported(DynamicConfigEvent event) {
+ ResourceId rsId = event.subject();
+ List<NodeKey> storeKeys = rsId.nodeKeys();
+ List<NodeKey> regKeys = id.nodeKeys();
+ if (storeKeys != null) {
+ if (storeKeys.size() == 1) {
+ return storeKeys.get(0).equals(regKeys.get(1)) &&
+ (event.type() == NODE_ADDED ||
+ event.type() == NODE_DELETED);
+ }
+ }
+ return false;
+ }
+
+ /***
+ * Creation of all configuration in standard device model.
+ *
+ * @param l3VpnSvc l3VPN service object
+ */
+ void createGlobalConfig(L3VpnSvc l3VpnSvc) {
+ if (l3VpnSvc.vpnServices() != null) {
+ createVpnServices(l3VpnSvc.vpnServices());
+ }
+ if (l3VpnSvc.sites() != null) {
+ createInterfaceConfig(l3VpnSvc.sites());
+ }
+ }
+
+ /**
+ * Creates the VPN instances from the VPN services object, if only that
+ * VPN instance is not already created.
+ *
+ * @param vpnSvcs VPN services object
+ */
+ private void createVpnServices(VpnServices vpnSvcs) {
+ if (vpnSvcs != null && vpnSvcs.vpnSvc() != null) {
+ List<VpnSvc> svcList = vpnSvcs.vpnSvc();
+ for (VpnSvc svc : svcList) {
+ String vpnName = svc.vpnId().string();
+ l3VpnStore.addVpnInsIfAbsent(vpnName, new VpnInstance(vpnName));
+ }
+ }
+ }
+
+ /**
+ * Creates interface configuration from the site network access if
+ * available.
+ *
+ * @param sites sites object
+ */
+ private void createInterfaceConfig(Sites sites) {
+ if (sites.site() != null) {
+ List<Site> sitesList = sites.site();
+ for (Site site : sitesList) {
+ if (site.siteNetworkAccesses() != null) {
+ SiteNetworkAccesses accesses = site.siteNetworkAccesses();
+ List<SiteNetworkAccess> accessList =
+ accesses.siteNetworkAccess();
+ for (SiteNetworkAccess access : accessList) {
+ createFromAccess(access, site.siteId().string());
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Creates the interface and VPN related configurations from the access
+ * and site id value.
+ *
+ * @param access site network access
+ * @param siteId site id
+ */
+ private void createFromAccess(SiteNetworkAccess access, String siteId) {
+ Map<AccessInfo, InterfaceInfo> intMap = l3VpnStore.getInterfaceInfo();
+ Map<String, VpnInstance> insMap = l3VpnStore.getVpnInstances();
+ String accessId = access.siteNetworkAccessId().string();
+ AccessInfo info = new AccessInfo(siteId, accessId);
+
+ if (intMap.get(info) == null) {
+ VpnSiteRole siteRole = getSiteRole(access.vpnAttachment());
+ VpnInstance instance = insMap.get(siteRole.name());
+ if (instance == null) {
+ throw new NetL3VpnException(SITE_VPN_MISMATCH);
+ }
+ buildFromAccess(instance, info, access, siteRole);
+ }
+ }
+
+ /**
+ * Returns the VPN site role from the VPN attachment.
+ *
+ * @param attach VPN attachment
+ * @return VPN site role
+ */
+ private VpnSiteRole getSiteRole(VpnAttachment attach) {
+ if (attach == null || attach.attachmentFlavor() == null) {
+ throw new NetL3VpnException(VPN_ATTACHMENT_NULL);
+ }
+ AttachmentFlavor flavor = attach.attachmentFlavor();
+ if (!(flavor instanceof DefaultVpnId)) {
+ throw new NetL3VpnException(VPN_POLICY_NOT_SUPPORTED);
+ }
+ DefaultVpnId vpnId = (DefaultVpnId) flavor;
+ if (vpnId.siteRole() == null) {
+ throw new NetL3VpnException(SITE_ROLE_NULL);
+ }
+ VpnType role = getRole(vpnId.siteRole());
+ VpnSiteRole vpnRole = new VpnSiteRole(
+ String.valueOf(vpnId.vpnId()), role);
+ return vpnRole;
+ }
+
+ /**
+ * Builds the required details for device standard model from the site
+ * network access info available.
+ *
+ * @param instance VPN instance
+ * @param info access info
+ * @param access network access
+ * @param role VPN site role
+ */
+ private void buildFromAccess(VpnInstance instance, AccessInfo info,
+ SiteNetworkAccess access, VpnSiteRole role) {
+ Bearer bearer = access.bearer();
+ if (bearer == null) {
+ throw new NetL3VpnException(BEARER_NULL);
+ }
+
+ RequestedType reqType = bearer.requestedType();
+ IpConnection connect = access.ipConnection();
+ RoutingProtocols pro = access.routingProtocols();
+
+ if (reqType == null || connect == null) {
+ throw new NetL3VpnException(IP_INT_INFO_NULL);
+ }
+ buildDeviceDetails(instance, info, role, bearer, connect,
+ reqType, pro);
+ }
+
+ /**
+ * Builds the device details such as, VPN instance value if it is for
+ * the first time, interface values and BGP info if available in service.
+ *
+ * @param instance VPN instance
+ * @param accInfo access info
+ * @param role VPN site role
+ * @param bearer bearer object
+ * @param connect ip connect object
+ * @param reqType requested type
+ * @param pro routing protocol
+ */
+ private void buildDeviceDetails(VpnInstance instance, AccessInfo accInfo,
+ VpnSiteRole role, Bearer bearer,
+ IpConnection connect, RequestedType reqType,
+ RoutingProtocols pro) {
+ Map<AccessInfo, InterfaceInfo> interMap = l3VpnStore.getInterfaceInfo();
+ InterfaceInfo intInfo = interMap.get(accInfo);
+ if (intInfo != null) {
+ return;
+ }
+
+ DeviceInfo info = buildDevVpnIns(bearer, instance, role, connect);
+ String portName = getInterfaceName(info, reqType);
+ buildDevVpnInt(info, instance, connect, portName, accInfo);
+
+ if (pro != null && pro.routingProtocol() != null) {
+ buildBgpInfo(pro.routingProtocol(), info,
+ role.name(), connect, accInfo);
+ }
+ InterfaceInfo interInfo = new InterfaceInfo(info, portName,
+ instance.vpnName());
+ l3VpnStore.addInterfaceInfo(accInfo, interInfo);
+ }
+
+ /**
+ * Builds device VPN instance with the service objects. It returns
+ *
+ * @param bearer bearer object
+ * @param ins VPN instance
+ * @param role VPN site role
+ * @param connect ip connection
+ * @return return
+ */
+ private DeviceInfo buildDevVpnIns(Bearer bearer, VpnInstance ins,
+ VpnSiteRole role, IpConnection connect) {
+ DefaultAugmentedL3VpnBearer augBearer = ((DefaultBearer) bearer)
+ .augmentation(DefaultAugmentedL3VpnBearer.class);
+ DeviceId id = getDeviceId(augBearer);
+ Map<DeviceId, DeviceInfo> devices = ins.devInfo();
+ DeviceInfo info = null;
+ if (devices != null) {
+ info = devices.get(id);
+ }
+ if (info == null) {
+ info = createVpnInstance(id, role, ins, connect);
+ }
+ return info;
+ }
+
+ /**
+ * Returns the device id from the bearer augment attachment of service.
+ * If the attachment in augment is not available it throws error.
+ *
+ * @param attach augmented bearer
+ * @return device id
+ */
+ private DeviceId getDeviceId(DefaultAugmentedL3VpnBearer attach) {
+ if (attach == null || attach.bearerAttachment() == null ||
+ attach.bearerAttachment().peMgmtIp() == null ||
+ attach.bearerAttachment().peMgmtIp().string() == null) {
+ 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(MG_MT_ADD);
+ if (ip.equals(val)) {
+ return device.id();
+ }
+ }
+ throw new NetL3VpnException(getMgmtIpUnAvailErr(ip));
+ }
+
+ /**
+ * Creates the VPN instance by constructing standard device model of
+ * instances. It adds the RD and RT values to the VPN instance.
+ *
+ * @param id device id
+ * @param role VPN site role
+ * @param inst VPN instance
+ * @param ip ip connection
+ * @return device info
+ */
+ private DeviceInfo createVpnInstance(DeviceId id, VpnSiteRole role,
+ VpnInstance inst, IpConnection ip) {
+ Map<AccessInfo, InterfaceInfo> intMap = l3VpnStore.getInterfaceInfo();
+ generateRdRt(inst, role);
+ DeviceInfo info = new DeviceInfo(id);
+ inst.addDevInfo(id, info);
+
+ NetworkInstances instances = createInstance(inst, role, ip);
+ ModelObjectData devMod = getVpnCreateModObj(intMap, instances,
+ id.toString());
+ ModelObjectData driMod = info.processCreateInstance(driverService,
+ devMod);
+ ResourceData resData = modelConverter.createDataNode(driMod);
+ addToStore(resData);
+ return info;
+ }
+
+ /**
+ * Adds the resource data that is received from the driver, after
+ * converting from the model object data.
+ *
+ * @param resData resource data
+ */
+ private void addToStore(ResourceData resData) {
+ if (resData != null && resData.dataNodes() != null) {
+ List<DataNode> dataNodes = resData.dataNodes();
+ for (DataNode node : dataNodes) {
+ configService.createNodeRecursive(resData.resourceId(), node);
+ }
+ }
+ }
+
+ /**
+ * Generates RD and RT value for the VPN instance for the first time VPN
+ * instance creation.
+ *
+ * @param ins VPN instance
+ * @param role VPN site role
+ */
+ private void generateRdRt(VpnInstance ins, VpnSiteRole role) {
+ ins.type(role.role());
+ VpnConfig config = ins.vpnConfig();
+ String rd = null;
+ if (config == null) {
+ rd = getIdFromGen();
+ }
+ switch (ins.type()) {
+ case ANY_TO_ANY:
+ if (config == null) {
+ config = new FullMeshVpnConfig(rd);
+ config.rd(rd);
+ }
+ break;
+
+ case HUB:
+ case SPOKE:
+ if (config == null) {
+ config = new HubSpokeVpnConfig();
+ config.rd(rd);
+ }
+ createImpRtVal((HubSpokeVpnConfig) config, ins.type());
+ createExpRtVal((HubSpokeVpnConfig) config, ins.type());
+ break;
+
+ default:
+ throw new NetL3VpnException(VPN_TYPE_UNSUPPORTED);
+ }
+ ins.vpnConfig(config);
+ }
+
+ /**
+ * Creates import RT value for HUB and SPOKE, according to the type, if
+ * the values are not present.
+ *
+ * @param config VPN config
+ * @param type VPN type
+ */
+ private void createImpRtVal(HubSpokeVpnConfig config, VpnType type) {
+ if (type == HUB) {
+ if (config.hubImpRt() != null) {
+ return;
+ }
+ setHubImpRt(config);
+ } else {
+ if (config.spokeImpRt() != null) {
+ return;
+ }
+ config.spokeImpRt(config.rd());
+ }
+ }
+
+ /**
+ * Sets the HUB import RT, from the spoke export RT. If it is not
+ * available a new ID is generated.
+ *
+ * @param config VPN config
+ */
+ public void setHubImpRt(HubSpokeVpnConfig config) {
+ String hubImp;
+ if (config.spokeExpRt() != null) {
+ hubImp = config.spokeExpRt();
+ } else {
+ hubImp = getIdFromGen();
+ }
+ config.hubImpRt(hubImp);
+ }
+
+ /**
+ * Creates export RT value for HUB and SPOKE, according to the type, if
+ * the values are not present.
+ *
+ * @param config VPN config
+ * @param type VPN type
+ */
+ private void createExpRtVal(HubSpokeVpnConfig config, VpnType type) {
+ if (type == HUB) {
+ if (config.hubExpRt() != null) {
+ return;
+ }
+ config.hubExpRt(config.rd());
+ } else {
+ if (config.spokeExpRt() != null) {
+ return;
+ }
+ setSpokeExpRt(config);
+ }
+ }
+
+ /**
+ * Sets the SPOKE export RT, from the hub import RT. If it is not
+ * available a new ID is generated.
+ *
+ * @param config VPN config
+ */
+ public void setSpokeExpRt(HubSpokeVpnConfig config) {
+ String spokeExp;
+ if (config.hubImpRt() != null) {
+ spokeExp = config.hubImpRt();
+ } else {
+ spokeExp = getIdFromGen();
+ }
+ config.spokeExpRt(spokeExp);
+ }
+
+ /**
+ * Returns the interface name from the requested type service object.
+ *
+ * @param info device info
+ * @param reqType requested type
+ * @return interface name
+ */
+ private String getInterfaceName(DeviceInfo info, RequestedType reqType) {
+ DefaultAugmentedL3VpnRequestedType req =
+ ((DefaultRequestedType) reqType).augmentation(
+ DefaultAugmentedL3VpnRequestedType.class);
+ if (req == null || req.requestedTypeProfile() == null ||
+ req.requestedTypeProfile().requestedTypeChoice() == null) {
+ throw new NetL3VpnException(INT_INFO_NULL);
+ }
+ RequestedTypeChoice reqChoice = req.requestedTypeProfile()
+ .requestedTypeChoice();
+ return getNameFromChoice(reqChoice, info.deviceId());
+ }
+
+ /**
+ * Returns the interface name from the type choice provided.
+ *
+ * @param choice service choice
+ * @param id device id
+ * @return interface name
+ */
+ private String getNameFromChoice(RequestedTypeChoice choice, DeviceId id) {
+ if (choice == null) {
+ throw new NetL3VpnException(INT_INFO_NULL);
+ }
+ String intName;
+ if (choice instanceof DefaultDot1Qcase) {
+ if (((DefaultDot1Qcase) choice).dot1q() == null ||
+ ((DefaultDot1Qcase) choice).dot1q()
+ .physicalIf() == null) {
+ throw new NetL3VpnException(INT_INFO_NULL);
+ }
+ intName = ((DefaultDot1Qcase) choice).dot1q().physicalIf();
+ } else {
+ if (((DefaultPhysicalCase) choice).physical() == null ||
+ ((DefaultPhysicalCase) choice).physical()
+ .physicalIf() == null) {
+ throw new NetL3VpnException(INT_INFO_NULL);
+ }
+ intName = ((DefaultPhysicalCase) choice).physical().physicalIf();
+ }
+ return getPortName(intName, id);
+ }
+
+ /**
+ * Returns the port name when it the port is available in the device.
+ *
+ * @param intName interface name
+ * @param id device id
+ * @return port name
+ */
+ private String getPortName(String intName, DeviceId id) {
+ List<Port> ports = deviceService.getPorts(id);
+ for (Port port : ports) {
+ String pName = port.annotations().value(PORT_NAME);
+ if (pName.equals(intName)) {
+ return intName;
+ }
+ }
+ throw new NetL3VpnException(getIntNotAvailable(intName));
+ }
+
+ /**
+ * Builds the interface for the device binding with the VPN instance.
+ *
+ * @param info device info
+ * @param ins VPN instance
+ * @param connect IP connection
+ * @param pName port name
+ * @param access access info
+ */
+ private void buildDevVpnInt(DeviceInfo info, VpnInstance ins,
+ IpConnection connect, String pName,
+ AccessInfo access) {
+ Map<AccessInfo, InterfaceInfo> intMap = l3VpnStore.getInterfaceInfo();
+ info.addAccessInfo(access);
+ info.addIfName(pName);
+ Interfaces interfaces = createInterface(pName, ins.vpnName(),
+ connect);
+ ModelObjectData devMod = getIntCreateModObj(
+ intMap, interfaces, info.deviceId().toString());
+ ModelObjectData driMod = info.processCreateInterface(driverService,
+ devMod);
+ ResourceData resData = modelConverter.createDataNode(driMod);
+ addToStore(resData);
+ }
+
+ /**
+ * Builds the BGP information from the routes that are given from the
+ * service.
+ *
+ * @param routes routing protocol
+ * @param info device info
+ * @param name VPN name
+ * @param connect IP connection
+ * @param access access info
+ */
+ private void buildBgpInfo(List<RoutingProtocol> routes, DeviceInfo info,
+ String name, IpConnection connect,
+ AccessInfo access) {
+ Map<BgpInfo, DeviceId> bgpMap = l3VpnStore.getBgpInfo();
+ BgpInfo intBgp = createBgpInfo(routes, info, name, connect, access);
+ if (intBgp != null) {
+ intBgp.vpnName(name);
+ BgpDriverInfo config = getBgpCreateConfigObj(
+ bgpMap, info.deviceId().toString());
+ ModelObjectData driData = info.processCreateBgpInfo(
+ driverService, intBgp, config);
+ l3VpnStore.addBgpInfo(info.bgpInfo(), info.deviceId());
+ ResourceData resData = modelConverter.createDataNode(driData);
+ addToStore(resData);
+ }
+ }
+
+ /**
+ * Representation of internal listener, listening for dynamic config event.
+ */
+ private class InternalConfigListener implements DynamicConfigListener {
+
+ @Override
+ public boolean isRelevant(DynamicConfigEvent event) {
+ return isSupported(event);
+ }
+
+ @Override
+ public void event(DynamicConfigEvent event) {
+ executor.execute(() -> {
+ try {
+ ResourceId rsId = event.subject();
+ switch (event.type()) {
+ case NODE_ADDED:
+ processCreateFromStore(rsId);
+ break;
+
+ case NODE_DELETED:
+ //TODO: To be committed.
+ break;
+
+ default:
+ throw new NetL3VpnException(EVENT_NOT_SUPPORTED);
+ }
+ } catch (Exception e) {
+ log.warn("Failed to process {}", event, e);
+ }
+ });
+ }
+ }
}