diff --git a/apps/l3vpn/BUCK b/apps/l3vpn/BUCK index 1a594673f6..1ac39c1493 100644 --- a/apps/l3vpn/BUCK +++ b/apps/l3vpn/BUCK @@ -7,6 +7,8 @@ COMPILE_DEPS = [ '//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 13bc818890..54ee93a119 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 @@ public class BgpDriverInfo { /** * 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 @@ public class BgpDriverInfo { * @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 @@ public class BgpDriverInfo { * * @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 20cf1c5df3..9a2c49aafd 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; @@ -36,6 +35,11 @@ public class DeviceInfo { */ private final DeviceId deviceId; + /** + * Type of the VPN. + */ + private final VpnType type; + /** * BGP information of the device. */ @@ -52,12 +56,24 @@ public class DeviceInfo { private List accesses; /** - * Constructs device info with a device id. + * List of tunnel names belonging to the device. + */ + private List 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; } /** @@ -69,6 +85,15 @@ public class DeviceInfo { return deviceId; } + /** + * Returns the type of the VPN instance. + * + * @return VPN type + */ + public VpnType type() { + return type; + } + /** * Adds a interface name to the list. * @@ -99,6 +124,56 @@ public class DeviceInfo { this.ifNames = ifNames; } + /*** + * Returns the list of tunnel names. + * + * @return tunnel names + */ + public List tnlNames() { + return tnlNames; + } + + /** + * Sets the list of tunnel names. + * + * @param tnlNames tunnel names + */ + public void tnlNames(List 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 class DeviceInfo { 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 class DeviceInfo { public ModelObjectData processCreateInterface(DriverService driverSvc, ModelObjectData modData) { L3VpnConfig config = getL3VpnConfig(driverSvc); - return (ModelObjectData) config.bindInterface(modData); + return config.bindInterface(modData); } /** @@ -191,7 +266,67 @@ public class DeviceInfo { 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 class DeviceInfo { public ModelObjectData processDeleteInstance(DriverService driverSvc, ModelObjectData modData) { L3VpnConfig config = getL3VpnConfig(driverSvc); - return (ModelObjectData) config.deleteInstance(modData); + return config.deleteInstance(modData); } /** @@ -238,7 +373,22 @@ public class DeviceInfo { 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/core/api/src/main/java/org/onosproject/net/behaviour/L3VpnConfig.java b/apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/L3VpnConfig.java similarity index 58% rename from core/api/src/main/java/org/onosproject/net/behaviour/L3VpnConfig.java rename to apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/L3VpnConfig.java index de63d46074..bfc8164816 100644 --- a/core/api/src/main/java/org/onosproject/net/behaviour/L3VpnConfig.java +++ b/apps/l3vpn/src/main/java/org/onosproject/l3vpn/netl3vpn/L3VpnConfig.java @@ -14,16 +14,14 @@ * limitations under the License. */ -package org.onosproject.net.behaviour; +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. - * - * @deprecated in 1.11.0 ("Loon") release */ -@Deprecated public interface L3VpnConfig extends HandlerBehaviour { /** @@ -33,7 +31,7 @@ public interface L3VpnConfig extends HandlerBehaviour { * @param objectData standard device model object data * @return device model object data */ - Object createInstance(Object objectData); + ModelObjectData createInstance(ModelObjectData objectData); /** * Binds requested virtual routing forwarding instance to interface on the @@ -42,7 +40,7 @@ public interface L3VpnConfig extends HandlerBehaviour { * @param objectData standard device model object data * @return device model object data */ - Object bindInterface(Object objectData); + ModelObjectData bindInterface(ModelObjectData objectData); /** * Deletes virtual routing forwarding instance on requested device with @@ -51,7 +49,7 @@ public interface L3VpnConfig extends HandlerBehaviour { * @param objectData standard device model object data * @return device model object data */ - Object deleteInstance(Object objectData); + ModelObjectData deleteInstance(ModelObjectData objectData); /** * Unbinds requested virtual routing forwarding instance to interface on the @@ -60,7 +58,15 @@ public interface L3VpnConfig extends HandlerBehaviour { * @param objectData standard device model object data * @return device model object data */ - Object unbindInterface(Object objectData); + 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 @@ -70,7 +76,7 @@ public interface L3VpnConfig extends HandlerBehaviour { * @param bgpConfig BGP driver config * @return device model object data */ - Object createBgpInfo(Object bgpInfo, Object bgpConfig); + ModelObjectData createBgpInfo(BgpInfo bgpInfo, BgpDriverInfo bgpConfig); /** * Deletes BGP routing protocol info on requested device with given @@ -80,5 +86,38 @@ public interface L3VpnConfig extends HandlerBehaviour { * @param bgpConfig BGP driver config * @return device model object data */ - Object deleteBgpInfo(Object bgpInfo, Object bgpConfig); + 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 72% 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 e5c76b1b09..91bf24844c 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 @@ public enum BgpModelIdLevel { /** * 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 8d638091b1..db926a208e 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 @@ -54,6 +54,13 @@ public interface NetL3VpnStore { */ Map getInterfaceInfo(); + /** + * Returns the tunnel information map available in the store, for a device. + * + * @return tunnel info map + */ + Map getTunnelInfo(); + /** * Adds freed id to the freed list in the store. * @@ -94,6 +101,14 @@ public interface NetL3VpnStore { */ 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. * @@ -127,4 +142,13 @@ public interface NetL3VpnStore { * @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 0000000000..db8c9c6770 --- /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 6fa2cfd98f..28a90da0b5 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.InterfaceInfo; 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 @@ public class DistributedNetL3VpnStore implements NetL3VpnStore { .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 @@ public class DistributedNetL3VpnStore implements NetL3VpnStore { */ private ConsistentMap bgpInfoMap; + /** + * Map of device id and tunnel count. + */ + private ConsistentMap tunnelInfoMap; + @Activate protected void activate() { vpnInsMap = storageService.consistentMapBuilder() @@ -134,6 +141,11 @@ public class DistributedNetL3VpnStore implements NetL3VpnStore { .withSerializer(L3VPN_SERIALIZER) .build(); + tunnelInfoMap = storageService.consistentMapBuilder() + .withName("onos-l3vpn-tnl-info-map") + .withSerializer(L3VPN_SERIALIZER) + .build(); + freedIdList = storageService.setBuilder() .withName("onos-l3vpn-id-freed-list") .withSerializer(Serializer.using(KryoNamespaces.API)) @@ -174,6 +186,13 @@ public class DistributedNetL3VpnStore implements NetL3VpnStore { .value())); } + @Override + public Map 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); @@ -203,11 +222,17 @@ public class DistributedNetL3VpnStore implements NetL3VpnStore { @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 @@ public class DistributedNetL3VpnStore implements NetL3VpnStore { } 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 cc0d51ea76..3b45c7d1fb 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.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.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.l3vpnsv 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.EVENT_NULL; 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_ATTACHMENT_NU 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 @@ 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 TNL_ID_TOPIC = "l3vpn-tnl-id"; private final Logger log = LoggerFactory.getLogger(getClass()); @@ -180,8 +178,13 @@ public class NetL3VpnManager { @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 @@ public class NetL3VpnManager { 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 @@ public class NetL3VpnManager { */ 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 devices = ins.devInfo(); DeviceInfo info = null; @@ -554,24 +563,7 @@ public class NetL3VpnManager { 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,20 +580,45 @@ public class NetL3VpnManager { VpnInstance inst, IpConnection ip) { Map 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 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 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 @@ public class NetL3VpnManager { * @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 @@ public class NetL3VpnManager { 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 0000000000..edef00a768 --- /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 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 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 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 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 tnlNames = info.tnlNames(); + for (String tnlName : tnlNames) { + Iterable 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 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 1dbb008cab..1fd03bd641 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.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.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; @@ -111,6 +111,11 @@ public final class NetL3VpnUtil { */ 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. */ @@ -169,11 +174,17 @@ public final class NetL3VpnUtil { */ 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 @@ public final class NetL3VpnUtil { } 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 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); + } } diff --git a/drivers/huawei/src/main/java/org/onosproject/drivers/huawei/BgpConstructionUtil.java b/drivers/huawei/src/main/java/org/onosproject/drivers/huawei/BgpConstructionUtil.java index 4f82a4aacd..b385252c15 100644 --- a/drivers/huawei/src/main/java/org/onosproject/drivers/huawei/BgpConstructionUtil.java +++ b/drivers/huawei/src/main/java/org/onosproject/drivers/huawei/BgpConstructionUtil.java @@ -18,7 +18,7 @@ package org.onosproject.drivers.huawei; import org.onosproject.l3vpn.netl3vpn.BgpDriverInfo; import org.onosproject.l3vpn.netl3vpn.BgpInfo; -import org.onosproject.l3vpn.netl3vpn.BgpModelIdLevel; +import org.onosproject.l3vpn.netl3vpn.ModelIdLevel; import org.onosproject.l3vpn.netl3vpn.ProtocolInfo; import org.onosproject.l3vpn.netl3vpn.RouteProtocol; import org.onosproject.yang.gen.v1.nebgpcomm.rev20141225.nebgpcomm.DefaultDevices; @@ -91,7 +91,7 @@ public final class BgpConstructionUtil { static ModelObjectData getCreateBgp(BgpInfo bgpInfo, BgpDriverInfo config) { String devId = config.devId(); - BgpModelIdLevel modIdLevel = config.modIdLevel(); + ModelIdLevel modIdLevel = config.modIdLevel(); Bgp bgp = new DefaultBgp(); Bgpcomm bgpBuilder = new DefaultBgpcomm(); @@ -246,7 +246,7 @@ public final class BgpConstructionUtil { * @param route import route object * @return model object data */ - public static ModelObjectData getModObjData(BgpModelIdLevel modIdLevel, + public static ModelObjectData getModObjData(ModelIdLevel modIdLevel, Bgp bgp, String devId, BgpVrf bgpVrf, ImportRoute route) { switch (modIdLevel) { @@ -371,7 +371,7 @@ public final class BgpConstructionUtil { */ static ModelObjectData getDeleteBgp(BgpInfo bgpInfo, BgpDriverInfo bgpConfig) { - BgpModelIdLevel modIdLvl = bgpConfig.modIdLevel(); + ModelIdLevel modIdLvl = bgpConfig.modIdLevel(); switch (modIdLvl) { case ROOT: return getDelRootModObj(); diff --git a/drivers/huawei/src/main/java/org/onosproject/drivers/huawei/HuaweiL3VpnConfig.java b/drivers/huawei/src/main/java/org/onosproject/drivers/huawei/HuaweiL3VpnConfig.java index 63519f2af8..2c08d3603a 100644 --- a/drivers/huawei/src/main/java/org/onosproject/drivers/huawei/HuaweiL3VpnConfig.java +++ b/drivers/huawei/src/main/java/org/onosproject/drivers/huawei/HuaweiL3VpnConfig.java @@ -21,7 +21,8 @@ import org.onosproject.config.DynamicConfigService; import org.onosproject.config.FailedException; import org.onosproject.l3vpn.netl3vpn.BgpDriverInfo; import org.onosproject.l3vpn.netl3vpn.BgpInfo; -import org.onosproject.net.behaviour.L3VpnConfig; +import org.onosproject.l3vpn.netl3vpn.L3VpnConfig; +import org.onosproject.l3vpn.netl3vpn.TunnelInfo; import org.onosproject.net.driver.AbstractHandlerBehaviour; import org.onosproject.yang.model.DataNode; import org.onosproject.yang.model.ModelObjectData; @@ -37,6 +38,11 @@ import static org.onosproject.drivers.huawei.DriverUtil.SLASH; import static org.onosproject.drivers.huawei.InsConstructionUtil.getCreateVpnIns; import static org.onosproject.drivers.huawei.InsConstructionUtil.getDeleteVpnIns; import static org.onosproject.drivers.huawei.IntConstructionUtil.getCreateInt; +import static org.onosproject.drivers.huawei.TnlConstructionUtil.getBindTnl; +import static org.onosproject.drivers.huawei.TnlConstructionUtil.getCreateTnl; +import static org.onosproject.drivers.huawei.TnlConstructionUtil.getCreateTnlDev; +import static org.onosproject.drivers.huawei.TnlConstructionUtil.getCreateTnlPol; +import static org.onosproject.drivers.huawei.TnlConstructionUtil.getDeleteTnl; /** * Configures l3vpn on Huawei devices. @@ -74,39 +80,64 @@ public class HuaweiL3VpnConfig extends AbstractHandlerBehaviour } @Override - public Object createInstance(Object objectData) { + public ModelObjectData createInstance(ModelObjectData objectData) { if (modelRegistry == null) { init(); } - return getCreateVpnIns((ModelObjectData) objectData, - isDevicesPresent()); + return getCreateVpnIns(objectData, isDevicesPresent()); } @Override - public Object bindInterface(Object objectData) { - return getCreateInt((ModelObjectData) objectData); + public ModelObjectData bindInterface(ModelObjectData objectData) { + return getCreateInt(objectData); } @Override - public Object createBgpInfo(Object bgpInfo, Object bgpConfig) { - return getCreateBgp((BgpInfo) bgpInfo, (BgpDriverInfo) bgpConfig); - } - - - @Override - public Object deleteInstance(Object objectData) { - return getDeleteVpnIns((ModelObjectData) objectData); + public ModelObjectData createBgpInfo(BgpInfo bgpInfo, + BgpDriverInfo bgpConfig) { + return getCreateBgp(bgpInfo, bgpConfig); } @Override - public Object unbindInterface(Object objectData) { + public ModelObjectData createTnlDev(TunnelInfo tnlInfo) { + return getCreateTnlDev(tnlInfo); + } + + @Override + public ModelObjectData createTnlPol(TunnelInfo tnlInfo) { + return getCreateTnlPol(tnlInfo); + } + + @Override + public ModelObjectData createTnl(TunnelInfo tnlInfo) { + return getCreateTnl(tnlInfo); + } + + @Override + public ModelObjectData bindTnl(TunnelInfo tnlInfo) { + return getBindTnl(tnlInfo); + } + + @Override + public ModelObjectData deleteInstance(ModelObjectData objectData) { + return getDeleteVpnIns(objectData); + } + + @Override + public ModelObjectData unbindInterface(ModelObjectData objectData) { //TODO:To be committed. return null; } @Override - public Object deleteBgpInfo(Object bgpInfo, Object bgpConfig) { - return getDeleteBgp((BgpInfo) bgpInfo, (BgpDriverInfo) bgpConfig); + public ModelObjectData deleteTnl(TunnelInfo tnlInfo) { + return getDeleteTnl(tnlInfo); + } + + @Override + public ModelObjectData deleteBgpInfo(BgpInfo bgpInfo, + BgpDriverInfo bgpConfig) { + return getDeleteBgp(bgpInfo, bgpConfig); } /** diff --git a/drivers/huawei/src/main/java/org/onosproject/drivers/huawei/HuaweiModelRegistrator.java b/drivers/huawei/src/main/java/org/onosproject/drivers/huawei/HuaweiModelRegistrator.java index b4b3732f71..9f175e885d 100644 --- a/drivers/huawei/src/main/java/org/onosproject/drivers/huawei/HuaweiModelRegistrator.java +++ b/drivers/huawei/src/main/java/org/onosproject/drivers/huawei/HuaweiModelRegistrator.java @@ -24,6 +24,8 @@ import org.onosproject.yang.gen.v1.nebgpcommtype.rev20141225.NeBgpcommType; import org.onosproject.yang.gen.v1.nel3vpnapi.rev20141225.NeL3VpnApi; import org.onosproject.yang.gen.v1.nel3vpncomm.rev20141225.NeL3Vpncomm; import org.onosproject.yang.gen.v1.nel3vpncommtype.rev20141225.NeL3VpncommType; +import org.onosproject.yang.gen.v1.netnlm.rev20141225.NeTnlm; +import org.onosproject.yang.gen.v1.netnlmtype.rev20141225.NeTnlmType; import org.onosproject.yang.model.DefaultYangModuleId; import org.onosproject.yang.model.YangModuleId; import org.onosproject.yang.runtime.AppModuleInfo; @@ -58,6 +60,10 @@ public class HuaweiModelRegistrator extends AbstractYangModelRegistrator { new DefaultAppModuleInfo(NeL3Vpncomm.class, null)); appInfo.put(new DefaultYangModuleId("ne-l3vpncomm-type", "2014-00-25"), new DefaultAppModuleInfo(NeL3VpncommType.class, null)); + appInfo.put(new DefaultYangModuleId("ne-tnlm", "2014-00-25"), + new DefaultAppModuleInfo(NeTnlm.class, null)); + appInfo.put(new DefaultYangModuleId("ne-tnlm-type", "2014-00-25"), + new DefaultAppModuleInfo(NeTnlmType.class, null)); return ImmutableMap.copyOf(appInfo); } } diff --git a/drivers/huawei/src/main/java/org/onosproject/drivers/huawei/InsConstructionUtil.java b/drivers/huawei/src/main/java/org/onosproject/drivers/huawei/InsConstructionUtil.java index 18b573a578..eb7fedf660 100644 --- a/drivers/huawei/src/main/java/org/onosproject/drivers/huawei/InsConstructionUtil.java +++ b/drivers/huawei/src/main/java/org/onosproject/drivers/huawei/InsConstructionUtil.java @@ -390,7 +390,7 @@ public final class InsConstructionUtil { * @param modObj model object data * @return driver model object data */ - static Object getDeleteVpnIns(ModelObjectData modObj) { + static ModelObjectData getDeleteVpnIns(ModelObjectData modObj) { ModelIdLevel modIdLvl = DEVICE; String id = getIdFromModId(modObj.identifier(), true); Object obj = getObjFromModData(modObj); @@ -472,7 +472,7 @@ public final class InsConstructionUtil { * @param id device id * @return model object id builder */ - private static ModelObjectId.Builder getModObjIdDriDevice(String id) { + static ModelObjectId.Builder getModObjIdDriDevice(String id) { DeviceKeys key = new DeviceKeys(); key.deviceid(id); return ModelObjectId.builder() diff --git a/drivers/huawei/src/main/java/org/onosproject/drivers/huawei/TnlConstructionUtil.java b/drivers/huawei/src/main/java/org/onosproject/drivers/huawei/TnlConstructionUtil.java new file mode 100644 index 0000000000..1ba29dd491 --- /dev/null +++ b/drivers/huawei/src/main/java/org/onosproject/drivers/huawei/TnlConstructionUtil.java @@ -0,0 +1,262 @@ +/* + * 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.drivers.huawei; + +import org.onosproject.l3vpn.netl3vpn.TunnelInfo; +import org.onosproject.yang.gen.v1.nel3vpncommtype.rev20141225.nel3vpncommtype.Ipv4Address; +import org.onosproject.yang.gen.v1.nel3vpncommtype.rev20141225.nel3vpncommtype.L3VpncommonL3VpnPrefixType; +import org.onosproject.yang.gen.v1.nel3vpnapi.rev20141225.nel3vpnapi.devices.device.DefaultL3Vpn; +import org.onosproject.yang.gen.v1.nel3vpnapi.rev20141225.nel3vpnapi.devices.device.l3vpn.DefaultL3Vpncomm; +import org.onosproject.yang.gen.v1.nel3vpnapi.rev20141225.nel3vpnapi.devices.device.l3vpn.l3vpncomm.DefaultL3VpnInstances; +import org.onosproject.yang.gen.v1.nel3vpnapi.rev20141225.nel3vpnapi.devices.device.l3vpn.l3vpncomm.l3vpninstances.DefaultL3VpnInstance; +import org.onosproject.yang.gen.v1.nel3vpnapi.rev20141225.nel3vpnapi.devices.device.l3vpn.l3vpncomm.l3vpninstances.L3VpnInstanceKeys; +import org.onosproject.yang.gen.v1.nel3vpnapi.rev20141225.nel3vpnapi.devices.device.l3vpn.l3vpncomm.l3vpninstances.l3vpninstance.DefaultVpnInstAfs; +import org.onosproject.yang.gen.v1.nel3vpnapi.rev20141225.nel3vpnapi.devices.device.l3vpn.l3vpncomm.l3vpninstances.l3vpninstance.vpninstafs.DefaultVpnInstAf; +import org.onosproject.yang.gen.v1.nel3vpnapi.rev20141225.nel3vpnapi.devices.device.l3vpn.l3vpncomm.l3vpninstances.l3vpninstance.vpninstafs.VpnInstAfKeys; +import org.onosproject.yang.gen.v1.netnlm.rev20141225.netnlm.DefaultDevices; +import org.onosproject.yang.gen.v1.netnlm.rev20141225.netnlm.Devices; +import org.onosproject.yang.gen.v1.netnlm.rev20141225.netnlm.devices.DefaultDevice; +import org.onosproject.yang.gen.v1.netnlm.rev20141225.netnlm.devices.Device; +import org.onosproject.yang.gen.v1.netnlm.rev20141225.netnlm.devices.DeviceKeys; +import org.onosproject.yang.gen.v1.netnlm.rev20141225.netnlm.devices.device.DefaultTnlm; +import org.onosproject.yang.gen.v1.netnlm.rev20141225.netnlm.devices.device.Tnlm; +import org.onosproject.yang.gen.v1.netnlm.rev20141225.netnlm.devices.device.tnlm.DefaultTunnelPolicys; +import org.onosproject.yang.gen.v1.netnlm.rev20141225.netnlm.devices.device.tnlm.TunnelPolicys; +import org.onosproject.yang.gen.v1.netnlm.rev20141225.netnlm.devices.device.tnlm.tunnelpolicys.DefaultTunnelPolicy; +import org.onosproject.yang.gen.v1.netnlm.rev20141225.netnlm.devices.device.tnlm.tunnelpolicys.TunnelPolicy; +import org.onosproject.yang.gen.v1.netnlm.rev20141225.netnlm.devices.device.tnlm.tunnelpolicys.TunnelPolicyKeys; +import org.onosproject.yang.gen.v1.netnlm.rev20141225.netnlm.devices.device.tnlm.tunnelpolicys.tunnelpolicy.DefaultTpNexthops; +import org.onosproject.yang.gen.v1.netnlm.rev20141225.netnlm.devices.device.tnlm.tunnelpolicys.tunnelpolicy.TpNexthops; +import org.onosproject.yang.gen.v1.netnlm.rev20141225.netnlm.devices.device.tnlm.tunnelpolicys.tunnelpolicy.tpnexthops.DefaultTpNexthop; +import org.onosproject.yang.gen.v1.netnlm.rev20141225.netnlm.devices.device.tnlm.tunnelpolicys.tunnelpolicy.tpnexthops.TpNexthop; +import org.onosproject.yang.gen.v1.netnlm.rev20141225.netnlm.devices.device.tnlm.tunnelpolicys.tunnelpolicy.tpnexthops.tpnexthop.DefaultTpTunnels; +import org.onosproject.yang.gen.v1.netnlm.rev20141225.netnlm.devices.device.tnlm.tunnelpolicys.tunnelpolicy.tpnexthops.tpnexthop.TpTunnels; +import org.onosproject.yang.gen.v1.netnlm.rev20141225.netnlm.devices.device.tnlm.tunnelpolicys.tunnelpolicy.tpnexthops.tpnexthop.tptunnels.DefaultTpTunnel; +import org.onosproject.yang.gen.v1.netnlm.rev20141225.netnlm.devices.device.tnlm.tunnelpolicys.tunnelpolicy.tpnexthops.tpnexthop.tptunnels.TpTunnel; +import org.onosproject.yang.gen.v1.netnlmtype.rev20141225.netnlmtype.tnlmbasetnlpolicytype.TnlmbaseTnlPolicyTypeEnum; +import org.onosproject.yang.model.DefaultModelObjectData; +import org.onosproject.yang.model.InnerModelObject; +import org.onosproject.yang.model.LeafModelObject; +import org.onosproject.yang.model.ModelObjectData; +import org.onosproject.yang.model.ModelObjectId.Builder; + +import static org.onosproject.drivers.huawei.DriverUtil.UNSUPPORTED_MODEL_LVL; +import static org.onosproject.drivers.huawei.DriverUtil.getData; +import static org.onosproject.drivers.huawei.InsConstructionUtil.getModObjIdDriDevice; +import static org.onosproject.l3vpn.netl3vpn.ModelIdLevel.TP_HOP; +import static org.onosproject.yang.gen.v1.nel3vpncommtype.rev20141225.nel3vpncommtype.l3vpncommonl3vpnprefixtype.L3VpncommonL3VpnPrefixTypeEnum.IPV4UNI; +import static org.onosproject.yang.gen.v1.nel3vpnapi.rev20141225.nel3vpnapi.devices.device.l3vpn.l3vpncomm.l3vpninstances.l3vpninstance.vpninstafs.VpnInstAf.LeafIdentifier.TNLPOLICYNAME; +import static org.onosproject.yang.gen.v1.netnlmtype.rev20141225.netnlmtype.TnlmbaseTnlPolicyType.of; +import static org.onosproject.yang.model.ModelObjectId.builder; + +/** + * Representation of utility for tunnel creation and deletion. + */ +public final class TnlConstructionUtil { + + /** + * Error message for unsupported device type. + */ + private static final String UNSUPPORTED_DEV_TYPE = "Levels other than " + + "devices and device are not permitted."; + + /** + * Error message for unsupported tunnel policy type. + */ + private static final String UNSUPPORTED_TNL_POL_TYPE = "Levels other" + + " than tnlm and tnl policy are not permitted."; + + // No instantiation. + private TnlConstructionUtil() { + } + + /** + * Returns the created model object data of devices or device level from + * the tunnel info. + * + * @param tnlInfo tunnel info + * @return driver model object data + */ + static ModelObjectData getCreateTnlDev(TunnelInfo tnlInfo) { + Device device = new DefaultDevice(); + device.deviceid(tnlInfo.devId()); + + switch (tnlInfo.level()) { + case DEVICES: + Devices devices = new DefaultDevices(); + devices.addToDevice(device); + return getData(null, (InnerModelObject) devices); + + case DEVICE: + Builder id = getDevicesId(); + return getData(id.build(), (InnerModelObject) device); + + default: + throw new IllegalArgumentException(UNSUPPORTED_DEV_TYPE); + } + } + + /** + * Returns the created model object data of tunnel policy from the tunnel + * info. + * + * @param tnlInfo tunnel info + * @return driver model object data + */ + static ModelObjectData getCreateTnlPol(TunnelInfo tnlInfo) { + Builder id = getDeviceId(tnlInfo.devId()); + TunnelPolicy tnlPol = new DefaultTunnelPolicy(); + tnlPol.tnlPolicyName(tnlInfo.polName()); + tnlPol.tnlPolicyType(of(TnlmbaseTnlPolicyTypeEnum.of(2))); + + switch (tnlInfo.level()) { + case TNL_M: + Tnlm tnlm = new DefaultTnlm(); + TunnelPolicys tnlPolicys = new DefaultTunnelPolicys(); + tnlPolicys.addToTunnelPolicy(tnlPol); + tnlm.tunnelPolicys(tnlPolicys); + return getData(id.build(), (InnerModelObject) tnlm); + + case TNL_POL: + id = getTunnelPolicysId(id); + return getData(id.build(), (InnerModelObject) tnlPol); + + default: + throw new IllegalArgumentException(UNSUPPORTED_TNL_POL_TYPE); + } + } + + /** + * Returns the created model object data of tunnel from the tunnel info. + * + * @param tnlInfo tunnel info + * @return driver model object data + */ + static ModelObjectData getCreateTnl(TunnelInfo tnlInfo) { + TunnelPolicyKeys key = new TunnelPolicyKeys(); + key.tnlPolicyName(tnlInfo.polName()); + + Builder id = getDeviceId(tnlInfo.devId()); + id = getTunnelPolicysId(id); + id = id.addChild(DefaultTunnelPolicy.class, key); + TpNexthop tpHop = new DefaultTpNexthop(); + TpTunnels tunnels = new DefaultTpTunnels(); + TpTunnel tunnel = new DefaultTpTunnel(); + tunnel.tunnelName(tnlInfo.tnlName()); + tunnel.autoTunnel(true); + tunnels.addToTpTunnel(tunnel); + tpHop.tpTunnels(tunnels); + tpHop.nexthopIpaddr(Ipv4Address.of(tnlInfo.desIp())); + + if (tnlInfo.level() == TP_HOP) { + id.addChild(DefaultTpNexthops.class); + return getData(id.build(), (InnerModelObject) tpHop); + } else { + TpNexthops tpHops = new DefaultTpNexthops(); + tpHops.addToTpNexthop(tpHop); + return getData(id.build(), (InnerModelObject) tpHops); + } + } + + /** + * Returns the created model object data of binding the tunnel policy to + * the VPN from the tunnel policy name and device id. + * + * @param tnlInfo tunnel info + * @return driver model object data + */ + static ModelObjectData getBindTnl(TunnelInfo tnlInfo) { + L3VpnInstanceKeys vpnKey = new L3VpnInstanceKeys(); + vpnKey.vrfName(tnlInfo.polName()); + VpnInstAfKeys afKeys = new VpnInstAfKeys(); + afKeys.afType(L3VpncommonL3VpnPrefixType.of(IPV4UNI)); + + Builder id = getModObjIdDriDevice(tnlInfo.devId()); + id.addChild(DefaultL3Vpn.class); + id.addChild(DefaultL3Vpncomm.class); + id.addChild(DefaultL3VpnInstances.class); + id.addChild(DefaultL3VpnInstance.class, vpnKey); + id.addChild(DefaultVpnInstAfs.class); + id.addChild(DefaultVpnInstAf.class, afKeys); + + LeafModelObject leaf = new LeafModelObject(); + leaf.leafIdentifier(TNLPOLICYNAME); + leaf.addValue(tnlInfo.polName()); + return DefaultModelObjectData.builder().addModelObject(leaf) + .identifier(id.build()).build(); + } + + /** + * Returns the driver model object data for delete, according to the + * levels it has to be constructed for tunnel policy. + * + * @param tnlInfo tunnel info + * @return driver model object data + */ + static ModelObjectData getDeleteTnl(TunnelInfo tnlInfo) { + Builder id = getDeviceId(tnlInfo.devId()); + switch (tnlInfo.level()) { + case DEVICES: + return getData(getDevicesId().build(), new DefaultDevice()); + + case DEVICE: + return getData(id.build(), new DefaultTnlm()); + + case TNL_POL: + id = getTunnelPolicysId(id); + TunnelPolicyKeys polKey = new TunnelPolicyKeys(); + polKey.tnlPolicyName(tnlInfo.polName()); + id = id.addChild(DefaultTunnelPolicy.class, polKey); + return getData(id.build(), new DefaultTpNexthops()); + + default: + throw new IllegalArgumentException(UNSUPPORTED_MODEL_LVL); + } + } + + /** + * Returns the model object id of tunnel with devices and device. + * + * @param id device id + * @return model object id + */ + private static Builder getDeviceId(String id) { + DeviceKeys devId = new DeviceKeys(); + devId.deviceid(id); + return getDevicesId().addChild(DefaultDevice.class, devId); + } + + /** + * Returns the model object id of tunnel with devices. + * + * @return model object id + */ + private static Builder getDevicesId() { + return builder().addChild(DefaultDevices.class); + } + + /** + * Returns the model object id of tunnel policies. + * + * @param id model object id + * @return model object id with tunnel policies + */ + public static Builder getTunnelPolicysId(Builder id) { + return id.addChild(DefaultTnlm.class) + .addChild(DefaultTunnelPolicys.class); + } +} diff --git a/drivers/huawei/src/main/resources/huawei-drivers.xml b/drivers/huawei/src/main/resources/huawei-drivers.xml index d1170c6072..0ec590d55f 100644 --- a/drivers/huawei/src/main/resources/huawei-drivers.xml +++ b/drivers/huawei/src/main/resources/huawei-drivers.xml @@ -17,7 +17,7 @@ - diff --git a/models/huawei/src/main/yang/ne-l3vpn-api.yang b/models/huawei/src/main/yang/ne-l3vpn-api.yang index 5b0181c012..5320617b3c 100644 --- a/models/huawei/src/main/yang/ne-l3vpn-api.yang +++ b/models/huawei/src/main/yang/ne-l3vpn-api.yang @@ -57,6 +57,9 @@ module ne-l3vpn-api { type "string"; description "route-distinguisher."; } + leaf tnlPolicyName { + type "string"; + } container vpnTargets { description ""; list vpnTarget { diff --git a/models/huawei/src/main/yang/ne-tnlm-type.yang b/models/huawei/src/main/yang/ne-tnlm-type.yang new file mode 100644 index 0000000000..8dac8e8fe4 --- /dev/null +++ b/models/huawei/src/main/yang/ne-tnlm-type.yang @@ -0,0 +1,30 @@ +/* +WARNING: +This yang model is just for fuction ONOS opensource project demo purpose only, +And is subject to change in future, Huawei does not commit provide compatibilty +in commercial product. +*/ +module ne-tnlm-type { + namespace "ne-tnlm-type"; + prefix tnlm-type; + organization "Huawei Technologies Co., Ltd"; + contact "Huawei Industrial Base + Bantian, Longgang + Shenzhen 518129 + People's Republic of China + Website: http://www.huawei.com + Email: support@huawei.com"; + description "VRP V800R010 Schema"; + + revision "2014-12-25" { + reference "Huawei VRPV8 Schema"; + } + + typedef tnlmbaseTnlPolicyType { + type enumeration { + enum invalid; + enum tnlSelectSeq; + enum tnlBinding; + } + } +} \ No newline at end of file diff --git a/models/huawei/src/main/yang/ne-tnlm.yang b/models/huawei/src/main/yang/ne-tnlm.yang new file mode 100644 index 0000000000..73796f4024 --- /dev/null +++ b/models/huawei/src/main/yang/ne-tnlm.yang @@ -0,0 +1,71 @@ +/* +WARNING: +This yang model is just for fuction ONOS opensource project demo purpose only, +And is subject to change in future, Huawei does not commit provide compatibilty +in commercial product. +*/ +module ne-tnlm { + namespace "ne-tnlm"; + prefix tnlm; + + import ne-l3vpncomm-type { + prefix l3vpncomm-type; + } + import ne-tnlm-type { + prefix tnlmtype; + } + organization "Huawei Technologies Co., Ltd"; + contact "Huawei Industrial Base + Bantian, Longgang + Shenzhen 518129 + People's Republic of China + Website: http://www.huawei.com + Email: support@huawei.com"; + description "VRP V800R010 Schema"; + revision "2014-12-25" { + reference "Huawei VRPV8 Schema"; + } + container devices { + list device { + key deviceid; + leaf deviceid { + type string; + } + container tnlm { + container tunnelPolicys { + list tunnelPolicy { + key tnlPolicyName; + leaf tnlPolicyName { + type string; + } + leaf tnlPolicyType { + type tnlmtype:tnlmbaseTnlPolicyType; + } + container tpNexthops { + list tpNexthop { + key nexthopIPaddr; + leaf nexthopIPaddr { + type "l3vpncomm-type:ipv4Address"; + } + leaf tnlPolicyName { + type string; + } + container tpTunnels { + list tpTunnel { + key "tunnelName"; + leaf autoTunnel { + type boolean; + } + leaf tunnelName { + type string; + } + } + } + } + } + } + } + } + } + } +} \ No newline at end of file