/* * 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.drivers.huawei; import org.onosproject.yang.gen.v1.ne.l3vpn.api.rev20141225.nel3vpnapi.devices.DefaultDevice; import org.onosproject.yang.gen.v1.ne.l3vpn.api.rev20141225.nel3vpnapi.devices.DeviceKeys; import org.onosproject.yang.gen.v1.ne.l3vpn.api.rev20141225.nel3vpnapi.devices.device.DefaultL3Vpn; import org.onosproject.yang.gen.v1.ne.l3vpn.api.rev20141225.nel3vpnapi.devices.device.L3Vpn; import org.onosproject.yang.gen.v1.ne.l3vpn.api.rev20141225.nel3vpnapi.devices.device.l3vpn.DefaultL3Vpncomm; import org.onosproject.yang.gen.v1.ne.l3vpn.api.rev20141225.nel3vpnapi.devices.device.l3vpn.L3Vpncomm; import org.onosproject.yang.gen.v1.ne.l3vpn.api.rev20141225.nel3vpnapi.devices.device.l3vpn.l3vpncomm.DefaultL3VpnInstances; import org.onosproject.yang.gen.v1.ne.l3vpn.api.rev20141225.nel3vpnapi.devices.device.l3vpn.l3vpncomm.L3VpnInstances; import org.onosproject.yang.gen.v1.ne.l3vpn.api.rev20141225.nel3vpnapi.devices.device.l3vpn.l3vpncomm.l3vpninstances.DefaultL3VpnInstance; import org.onosproject.yang.gen.v1.ne.l3vpn.api.rev20141225.nel3vpnapi.devices.device.l3vpn.l3vpncomm.l3vpninstances.L3VpnInstance; import org.onosproject.yang.gen.v1.ne.l3vpn.api.rev20141225.nel3vpnapi.devices.device.l3vpn.l3vpncomm.l3vpninstances.L3VpnInstanceKeys; import org.onosproject.yang.gen.v1.ne.l3vpn.api.rev20141225.nel3vpnapi.devices.device.l3vpn.l3vpncomm.l3vpninstances.l3vpninstance.DefaultVpnInstAfs; import org.onosproject.yang.gen.v1.ne.l3vpn.api.rev20141225.nel3vpnapi.devices.device.l3vpn.l3vpncomm.l3vpninstances.l3vpninstance.VpnInstAfs; import org.onosproject.yang.gen.v1.ne.l3vpn.api.rev20141225.nel3vpnapi.devices.device.l3vpn.l3vpncomm.l3vpninstances.l3vpninstance.vpninstafs.DefaultVpnInstAf; import org.onosproject.yang.gen.v1.ne.l3vpn.api.rev20141225.nel3vpnapi.devices.device.l3vpn.l3vpncomm.l3vpninstances.l3vpninstance.vpninstafs.VpnInstAf; import org.onosproject.yang.gen.v1.ne.l3vpn.api.rev20141225.nel3vpnapi.devices.device.l3vpn.l3vpncomm.l3vpninstances.l3vpninstance.vpninstafs.vpninstaf.DefaultVpnTargets; import org.onosproject.yang.gen.v1.ne.l3vpn.api.rev20141225.nel3vpnapi.devices.device.l3vpn.l3vpncomm.l3vpninstances.l3vpninstance.vpninstafs.vpninstaf.VpnTargets; import org.onosproject.yang.gen.v1.ne.l3vpn.api.rev20141225.nel3vpnapi.devices.device.l3vpn.l3vpncomm.l3vpninstances.l3vpninstance.vpninstafs.vpninstaf.vpntargets.DefaultVpnTarget; import org.onosproject.yang.gen.v1.ne.l3vpn.api.rev20141225.nel3vpnapi.devices.device.l3vpn.l3vpncomm.l3vpninstances.l3vpninstance.vpninstafs.vpninstaf.vpntargets.VpnTarget; import org.onosproject.yang.gen.v1.ne.l3vpn.comm.rev20141225.nel3vpncomm.l3vpnifs.DefaultL3VpnIfs; 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.l3vpnvrfparams.ipv4.Unicast; 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.network.instance.rev20160623.ietfnetworkinstance.DefaultDevices; 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.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 org.onosproject.yang.model.InnerModelObject; import org.onosproject.yang.model.ModelObjectData; import org.onosproject.yang.model.ModelObjectId; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import static org.onosproject.drivers.huawei.DriverUtil.CONS_DEVICES; import static org.onosproject.drivers.huawei.DriverUtil.DEVICE_NULL; import static org.onosproject.drivers.huawei.DriverUtil.INS_NULL; import static org.onosproject.drivers.huawei.DriverUtil.OBJECT_NULL; import static org.onosproject.drivers.huawei.DriverUtil.UNSUPPORTED_MODEL_LVL; import static org.onosproject.drivers.huawei.DriverUtil.getData; import static org.onosproject.drivers.huawei.DriverUtil.getIdFromModId; import static org.onosproject.drivers.huawei.DriverUtil.getModObjIdDriDevices; import static org.onosproject.drivers.huawei.DriverUtil.getObjFromModData; import static org.onosproject.drivers.huawei.ModelIdLevel.DEVICE; import static org.onosproject.drivers.huawei.ModelIdLevel.DEVICES; import static org.onosproject.drivers.huawei.ModelIdLevel.ROOT; import static org.onosproject.yang.gen.v1.l3vpn.comm.type.rev20141225.nel3vpncommtype.L3VpncommonL3VpnPrefixType.of; import static org.onosproject.yang.gen.v1.l3vpn.comm.type.rev20141225.nel3vpncommtype.L3VpncommonVrfRtType.fromString; import static org.onosproject.yang.gen.v1.l3vpn.comm.type.rev20141225.nel3vpncommtype.l3vpncommonl3vpnprefixtype.L3VpncommonL3VpnPrefixTypeEnum.IPV4UNI; import static org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.bgp.l3vpn.rev20160909.ietfbgpl3vpn.routetargetset.rts.RtTypeEnum.BOTH; /** * Representation of utility for instance creation and deletion. */ public final class InsConstructionUtil { /** * Static constant for route target export. */ private static final String EXP_COMM = "export_extcommunity"; /** * Static constant for route target import. */ private static final String IMP_COMM = "import_extcommunity"; /** * Error message for unsupported RT type. */ private static final String UNSUPPORTED_RT_TYPE = "The RT type is not " + "supported"; // No instantiation. private InsConstructionUtil() { } /** * Returns the created model object data of VPN instance of huawei device * from the standard model object data. * * @param modObj model object data * @param isDevAvail if devices available * @return driver model object data */ static ModelObjectData getCreateVpnIns(ModelObjectData modObj, boolean isDevAvail) { ModelIdLevel modIdLvl = DEVICE; String id = getIdFromModId(modObj.identifier(), true); Object obj = getObjFromModData(modObj); if (obj == null) { throw new IllegalArgumentException(OBJECT_NULL); } if (id == null) { id = getDevIdFromRootObj(obj); obj = getObjFromRootObj(obj); if (isDevAvail) { modIdLvl = DEVICES; } else { modIdLvl = ROOT; } } else if (id.equals(CONS_DEVICES)) { modIdLvl = DEVICES; id = ((Device) obj).deviceid(); obj = ((Device) obj).networkInstances(); } org.onosproject.yang.gen.v1.ne.l3vpn.api.rev20141225.nel3vpnapi .DefaultDevices devices = getDriverDevices( id, (NetworkInstances) obj); return getCreateModObjData(modIdLvl, id, devices); } /** * Returns the driver model object data, according to the levels it has * to be constructed. * * @param modIdLvl model id level * @param devId device id * @param devices devices object * @return model object data */ private static ModelObjectData getCreateModObjData(ModelIdLevel modIdLvl, String devId, org.onosproject.yang.gen .v1.ne.l3vpn.api .rev20141225 .nel3vpnapi .DefaultDevices devices) { ModelObjectId id; List<org.onosproject.yang.gen.v1.ne.l3vpn.api.rev20141225.nel3vpnapi .devices.Device> devList = devices.device(); Iterator<org.onosproject.yang.gen.v1.ne.l3vpn.api.rev20141225.nel3vpnapi .devices.Device> it = devList.iterator(); org.onosproject.yang.gen.v1.ne.l3vpn.api.rev20141225.nel3vpnapi .devices.Device device = it.next(); Iterator<L3VpnInstance> instIt = device.l3Vpn().l3Vpncomm() .l3VpnInstances().l3VpnInstance().iterator(); L3VpnInstance ins = instIt.next(); switch (modIdLvl) { case ROOT: return getData(null, devices); case DEVICES: id = getModObjIdDriDevices(); return getData(id, (InnerModelObject) device); case DEVICE: id = getModelObjIdForIns(devId).build(); return getData(id, (InnerModelObject) ins); default: throw new IllegalArgumentException(UNSUPPORTED_MODEL_LVL); } } /** * Returns the devices object of the huawei VPN instance model. This * constructs all the required information in the device for L3VPN * instance creation. * * @param id device id * @param obj network instances object * @return driver VPN instance's devices */ private static org.onosproject.yang.gen.v1.ne.l3vpn.api.rev20141225 .nel3vpnapi.DefaultDevices getDriverDevices(String id, NetworkInstances obj) { org.onosproject.yang.gen.v1.ne.l3vpn.api.rev20141225.nel3vpnapi. DefaultDevices devices = new org.onosproject.yang.gen.v1.ne .l3vpn.api.rev20141225.nel3vpnapi.DefaultDevices(); org.onosproject.yang.gen.v1.ne.l3vpn.api.rev20141225.nel3vpnapi.devices .Device device = new org.onosproject.yang.gen.v1.ne.l3vpn.api .rev20141225.nel3vpnapi.devices.DefaultDevice(); L3Vpn l3Vpn = new DefaultL3Vpn(); L3Vpncomm l3VpnComm = new DefaultL3Vpncomm(); L3VpnInstances instances = new DefaultL3VpnInstances(); L3VpnInstance ins = new DefaultL3VpnInstance(); List<L3VpnInstance> insList = new LinkedList<>(); List<org.onosproject.yang.gen.v1.ne.l3vpn.api.rev20141225.nel3vpnapi .devices.Device> devList = new LinkedList<>(); createDriIns(obj, ins); insList.add(ins); instances.l3VpnInstance(insList); l3VpnComm.l3VpnInstances(instances); l3Vpn.l3Vpncomm(l3VpnComm); device.deviceid(id); device.l3Vpn(l3Vpn); devList.add(device); devices.device(devList); return devices; } /** * Creates driver instance value from standard device instance. * * @param ins standard device instance * @param driIns driver instance */ private static void createDriIns(NetworkInstances ins, L3VpnInstance driIns) { NetworkInstance networkInstance = ins.networkInstance().iterator() .next(); driIns.vrfName(networkInstance.name()); DefaultAugmentedNiNetworkInstance augIns = ((DefaultNetworkInstance) networkInstance).augmentation( DefaultAugmentedNiNetworkInstance.class); VpnInstAfs vpnInstAfs = processL3VpnAf(augIns.l3Vpn()); driIns.vpnInstAfs(vpnInstAfs); } /** * Returns the device id from the root object. * * @param obj root object * @return device id */ private static String getDevIdFromRootObj(Object obj) { Device dev = getDevFromRootObj(obj); return dev.deviceid(); } /** * Returns the first device from the root object. If no device is * present, it returns null. * * @param obj root object * @return device object */ private static Device getDevFromRootObj(Object obj) { List<Device> deviceList = ((DefaultDevices) obj).device(); Iterator<Device> it = deviceList.iterator(); if (it.hasNext()) { return it.next(); } throw new IllegalArgumentException(DEVICE_NULL); } /** * Returns the network instances object from the root object. * * @param obj root object * @return network instances */ private static NetworkInstances getObjFromRootObj(Object obj) { Device dev = getDevFromRootObj(obj); return dev.networkInstances(); } /** * Returns model object id builder that has to be constructed for driver * instance level addition, with the device id. * * @param id device id * @return model object id */ private static ModelObjectId.Builder getModelObjIdForIns(String id) { ModelObjectId.Builder device = getModObjIdDriDevice(id); return device.addChild(DefaultL3Vpn.class) .addChild(DefaultL3Vpncomm.class) .addChild(DefaultL3VpnInstances.class); } /** * Processes standard device model L3VPN address family and returns the * driver L3VPN address family. * * @param l3Vpn standard device L3VPN * @return driver address family */ private static VpnInstAfs processL3VpnAf(org.onosproject.yang.gen.v1.urn .ietf.params.xml.ns.yang .ietf.bgp.l3vpn.rev20160909 .ietfbgpl3vpn.devices .device.networkinstances .networkinstance .augmentedninetworkinstance .L3Vpn l3Vpn) { // TODO: Need to handle the ipv6 case Unicast ipv4Unicast = l3Vpn.ipv4().unicast(); VpnInstAfs vpnInstAfs = new DefaultVpnInstAfs(); VpnInstAf vpnInstAf = new DefaultVpnInstAf(); VpnTargets vpnTargets = new DefaultVpnTargets(); List<VpnInstAf> afList = new LinkedList<>(); vpnInstAf.vrfRd(l3Vpn.routeDistinguisher().config().rd()); vpnInstAf.afType(of(IPV4UNI)); List<Rts> rts = ipv4Unicast.routeTargets().config().rts(); addVpnTarget(vpnTargets, rts); vpnInstAf.vpnTargets(vpnTargets); afList.add(vpnInstAf); vpnInstAfs.vpnInstAf(afList); return vpnInstAfs; } /** * Adds VPN target to the target list from the list of RTs available in * the standard device model. * * @param vpnTgts VPN targets * @param rts rts */ private static void addVpnTarget(VpnTargets vpnTgts, List<Rts> rts) { List<VpnTarget> tgtList = new LinkedList<>(); for (Rts rt : rts) { if (rt == null) { continue; } if (rt.rtType() == BOTH) { VpnTarget expTgt = addRt(rt.rt(), EXP_COMM); VpnTarget impTgt = addRt(rt.rt(), IMP_COMM); tgtList.add(expTgt); tgtList.add(impTgt); } else { String rtType = getRtVal(rt.rtType()); VpnTarget tgt = addRt(rt.rt(), rtType); tgtList.add(tgt); } } vpnTgts.vpnTarget(tgtList); } /** * Returns the RT value according to the RT type available. * * @param type RT type * @return RT value */ private static String getRtVal(RtTypeEnum type) { switch (type) { case EXPORT: return EXP_COMM; case IMPORT: return IMP_COMM; default: throw new IllegalArgumentException(UNSUPPORTED_RT_TYPE); } } /** * Adds RT to the VPN target with the RT value and RT type. * * @param rt RT value * @param rtType RT type * @return VPN target */ private static VpnTarget addRt(String rt, String rtType) { VpnTarget vpnTarget = new DefaultVpnTarget(); vpnTarget.vrfRtvalue(rt); vpnTarget.vrfRttype(fromString(rtType)); return vpnTarget; } /** * Returns the deletable model object data of VPN instance of huawei device * from the standard model object data. * * @param modObj model object data * @return driver model object data */ static Object getDeleteVpnIns(ModelObjectData modObj) { ModelIdLevel modIdLvl = DEVICE; String id = getIdFromModId(modObj.identifier(), true); Object obj = getObjFromModData(modObj); if (obj == null) { throw new IllegalArgumentException(OBJECT_NULL); } if (id == null) { modIdLvl = ROOT; id = getDevIdFromRootObj(obj); obj = getObjFromRootObj(obj); } else if (id.equals(CONS_DEVICES)) { modIdLvl = DEVICES; id = ((Device) obj).deviceid(); obj = ((Device) obj).networkInstances(); } List<NetworkInstance> ins = ((NetworkInstances) obj).networkInstance(); Iterator<NetworkInstance> it = ins.iterator(); NetworkInstance instance; if (it.hasNext()) { instance = it.next(); } else { throw new IllegalArgumentException(INS_NULL); } return getDelModObjData(modIdLvl, id, instance.name()); } /** * Returns the driver model object data for delete, according to the * levels it has to be constructed. * * @param modIdLvl model id level * @param id device id * @param name VPN name * @return driver model object data */ private static ModelObjectData getDelModObjData(ModelIdLevel modIdLvl, String id, String name) { ModelObjectId modId; switch (modIdLvl) { case ROOT: modId = getModObjIdDriDevices(); DefaultDevice device = new DefaultDevice(); return getData(modId, device); case DEVICES: DefaultL3Vpn l3Vpn = new DefaultL3Vpn(); modId = getModObjIdDriDevice(id).build(); return getData(modId, l3Vpn); case DEVICE: DefaultL3VpnIfs l3VpnIfs = new DefaultL3VpnIfs(); modId = getModObjIdDriVpn(id, name); return getData(modId, l3VpnIfs); default: throw new IllegalArgumentException(UNSUPPORTED_MODEL_LVL); } } /** * Returns the model object id, with device id and VPN name. * * @param id device id * @param name VPN name * @return model object id */ private static ModelObjectId getModObjIdDriVpn(String id, String name) { ModelObjectId.Builder ins = getModelObjIdForIns(id); L3VpnInstanceKeys key = new L3VpnInstanceKeys(); key.vrfName(name); return ins.addChild(DefaultL3VpnInstance.class, key).build(); } /** * Returns the model object id builder of the driver with respect to device. * * @param id device id * @return model object id builder */ private static ModelObjectId.Builder getModObjIdDriDevice(String id) { DeviceKeys key = new DeviceKeys(); key.deviceid(id); return ModelObjectId.builder() .addChild(org.onosproject.yang.gen.v1.ne.l3vpn.api.rev20141225 .nel3vpnapi.DefaultDevices.class) .addChild(DefaultDevice.class, key); } }