/* * Copyright (c) 2014 Ericsson India Global Services Pvt Ltd. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ package org.opendaylight.openflowplugin.openflow.md.core.sal.convertor; import com.google.common.annotations.VisibleForTesting; import java.util.Collection; import java.util.Collections; import java.util.Set; import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.common.Convertor; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionConvertorData; import org.opendaylight.openflowplugin.openflow.md.util.OpenflowPortsUtil; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.port.mod.port.Port; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortConfig; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortConfigV10; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeatures; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeaturesV10; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortState; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.desc._case.multipart.reply.port.desc.Ports; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.desc._case.multipart.reply.port.desc.PortsBuilder; import org.opendaylight.yangtools.yang.binding.DataContainer; /** * Converts port mod, port status and port description MD-SAL messages to OF library data * * Example usage: * <pre> * {@code * VersionConvertorData data = new VersionConvertorData(version); * Optional<PortModInput> ofPort = convertorManager.convert(salPort, data); * } * </pre> */ public class PortConvertor extends Convertor<Port, PortModInput, VersionConvertorData> { private static final Set<Class<? extends DataContainer>> TYPES = Collections.singleton(Port.class); /** * Create default empty port mod input * Use this method, if result from convertor is empty. * * @param version Openflow version * @return default empty port mod input */ public static PortModInput defaultResult(short version) { return new PortModInputBuilder() .setVersion(version) .build(); } private static PortConfig maskPortConfigFields( org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortConfig configData) { Boolean portDown = configData.isPORTDOWN(); Boolean noRecv = configData.isNORECV(); Boolean noFwd = configData.isNOFWD(); Boolean noPacketIn = configData.isNOPACKETIN(); return new PortConfig(noFwd, noPacketIn, noRecv, portDown); } private static PortConfigV10 maskPortConfigV10Fields( org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortConfig configData) { Boolean portDown = configData.isPORTDOWN(); Boolean noRecv = configData.isNORECV(); Boolean noFwd = configData.isNOFWD(); Boolean noPacketIn = configData.isNOPACKETIN(); return new PortConfigV10(false, noFwd, noPacketIn, noRecv, true, true, portDown); } private static PortFeatures getPortFeatures( org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortFeatures salPortFeatures) { return new PortFeatures(salPortFeatures.isHundredGbFd(), salPortFeatures.isHundredMbFd(), salPortFeatures.isHundredMbHd(), salPortFeatures.isTenGbFd(), salPortFeatures.isTenMbFd(), salPortFeatures.isTenMbHd(), salPortFeatures.isOneGbFd(), salPortFeatures.isOneGbHd(), salPortFeatures.isOneTbFd(), salPortFeatures.isFortyGbFd(), salPortFeatures.isAutoeng(), salPortFeatures.isCopper(), salPortFeatures.isFiber(), salPortFeatures.isOther(), salPortFeatures.isPause(), salPortFeatures.isPauseAsym()); } private static PortFeaturesV10 getPortFeaturesV10( org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortFeatures salPortFeatures) { return new PortFeaturesV10(salPortFeatures.isHundredMbFd(), salPortFeatures.isHundredMbHd(), salPortFeatures.isTenGbFd(), salPortFeatures.isTenMbFd(), salPortFeatures.isTenMbHd(), salPortFeatures.isOneGbFd(), salPortFeatures.isOneGbHd(), salPortFeatures.isAutoeng(), salPortFeatures.isCopper(), salPortFeatures.isFiber(), salPortFeatures.isPause(), salPortFeatures.isPauseAsym()); } /** * This method is called as a reply to OFPMP_PORT_DESCRIPTION * message(OF1.3.1) * * @param source FlowCapablePort * @param version openflow version * @return OF:Ports */ @VisibleForTesting static Ports toPortDesc( org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.FlowCapablePort source, short version) { PortsBuilder oFPortDescDataBuilder = new PortsBuilder(); oFPortDescDataBuilder.setPortNo( OpenflowPortsUtil.getProtocolPortNumber(OpenflowVersion.get(version), source.getPortNumber())); // portNO oFPortDescDataBuilder.setHwAddr(source.getHardwareAddress()); oFPortDescDataBuilder.setName(source.getName()); PortConfig config = maskPortConfigFields(source.getConfiguration()); oFPortDescDataBuilder.setConfig(config); PortState portState = getPortState(source.getState()); oFPortDescDataBuilder.setState(portState); oFPortDescDataBuilder.setCurrentFeatures(getPortFeatures(source.getCurrentFeature())); oFPortDescDataBuilder.setAdvertisedFeatures(getPortFeatures(source.getAdvertisedFeatures())); oFPortDescDataBuilder.setSupportedFeatures(getPortFeatures(source.getSupported())); oFPortDescDataBuilder.setPeerFeatures(getPortFeatures(source.getPeerFeatures())); oFPortDescDataBuilder.setCurrSpeed(source.getCurrentSpeed()); oFPortDescDataBuilder.setMaxSpeed(source.getMaximumSpeed()); return oFPortDescDataBuilder.build(); } private static PortState getPortState( org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortState state) { boolean isLinkDown = state.isLinkDown(); boolean isBlocked = state.isBlocked(); boolean isLive = state.isLive(); return new PortState(isLinkDown, isBlocked, isLive); } @Override public Collection<Class<? extends DataContainer>> getTypes() { return TYPES; } @Override public PortModInput convert(Port source, VersionConvertorData data) { PortConfig config = maskPortConfigFields(source.getConfiguration()); PortConfigV10 configV10 = maskPortConfigV10Fields(source.getConfiguration()); PortModInputBuilder portModInputBuilder = new PortModInputBuilder(); portModInputBuilder.setAdvertise(getPortFeatures(source.getAdvertisedFeatures())); portModInputBuilder.setPortNo(new PortNumber( OpenflowPortsUtil.getProtocolPortNumber(OpenflowVersion.get(data.getVersion()), source.getPortNumber()))); portModInputBuilder.setConfig(config); portModInputBuilder.setMask(config); portModInputBuilder.setHwAddress(new MacAddress(source.getHardwareAddress())); portModInputBuilder.setVersion(data.getVersion()); portModInputBuilder.setConfigV10(configV10); portModInputBuilder.setMaskV10(configV10); portModInputBuilder.setAdvertiseV10(getPortFeaturesV10(source.getAdvertisedFeatures())); return portModInputBuilder.build(); } }