Committed by
Gerrit Code Review
Add Oplink attenuation extension and channel power drivers.
Change-Id: I2558595b03cbb6cc58237dc48b8a03e83357fe1f
Showing
10 changed files
with
487 additions
and
13 deletions
| ... | @@ -61,7 +61,8 @@ public final class ExtensionTreatmentType { | ... | @@ -61,7 +61,8 @@ public final class ExtensionTreatmentType { |
| 61 | NICIRA_ENCAP_ETH_SRC(121), | 61 | NICIRA_ENCAP_ETH_SRC(121), |
| 62 | NICIRA_ENCAP_ETH_DST(122), | 62 | NICIRA_ENCAP_ETH_DST(122), |
| 63 | NICIRA_ENCAP_ETH_TYPE(123), | 63 | NICIRA_ENCAP_ETH_TYPE(123), |
| 64 | - BMV2_ACTION(128); | 64 | + BMV2_ACTION(128), |
| 65 | + OPLINK_ATTENUATION(130); | ||
| 65 | 66 | ||
| 66 | private ExtensionTreatmentType type; | 67 | private ExtensionTreatmentType type; |
| 67 | 68 | ... | ... |
| ... | @@ -32,6 +32,7 @@ import org.onosproject.driver.extensions.NiciraSetNshSpi; | ... | @@ -32,6 +32,7 @@ import org.onosproject.driver.extensions.NiciraSetNshSpi; |
| 32 | import org.onosproject.driver.extensions.NiciraSetTunnelDst; | 32 | import org.onosproject.driver.extensions.NiciraSetTunnelDst; |
| 33 | import org.onosproject.driver.extensions.OfdpaMatchVlanVid; | 33 | import org.onosproject.driver.extensions.OfdpaMatchVlanVid; |
| 34 | import org.onosproject.driver.extensions.OfdpaSetVlanVid; | 34 | import org.onosproject.driver.extensions.OfdpaSetVlanVid; |
| 35 | +import org.onosproject.driver.extensions.OplinkAttenuation; | ||
| 35 | import org.onosproject.driver.extensions.codec.MoveExtensionTreatmentCodec; | 36 | import org.onosproject.driver.extensions.codec.MoveExtensionTreatmentCodec; |
| 36 | import org.onosproject.driver.extensions.codec.NiciraMatchNshSiCodec; | 37 | import org.onosproject.driver.extensions.codec.NiciraMatchNshSiCodec; |
| 37 | import org.onosproject.driver.extensions.codec.NiciraMatchNshSpiCodec; | 38 | import org.onosproject.driver.extensions.codec.NiciraMatchNshSpiCodec; |
| ... | @@ -43,6 +44,7 @@ import org.onosproject.driver.extensions.codec.NiciraSetNshSpiCodec; | ... | @@ -43,6 +44,7 @@ import org.onosproject.driver.extensions.codec.NiciraSetNshSpiCodec; |
| 43 | import org.onosproject.driver.extensions.codec.NiciraSetTunnelDstCodec; | 44 | import org.onosproject.driver.extensions.codec.NiciraSetTunnelDstCodec; |
| 44 | import org.onosproject.driver.extensions.codec.OfdpaMatchVlanVidCodec; | 45 | import org.onosproject.driver.extensions.codec.OfdpaMatchVlanVidCodec; |
| 45 | import org.onosproject.driver.extensions.codec.OfdpaSetVlanVidCodec; | 46 | import org.onosproject.driver.extensions.codec.OfdpaSetVlanVidCodec; |
| 47 | +import org.onosproject.driver.extensions.codec.OplinkAttenuationCodec; | ||
| 46 | import org.slf4j.Logger; | 48 | import org.slf4j.Logger; |
| 47 | 49 | ||
| 48 | import static org.slf4j.LoggerFactory.getLogger; | 50 | import static org.slf4j.LoggerFactory.getLogger; |
| ... | @@ -71,6 +73,7 @@ public class DefaultCodecRegister { | ... | @@ -71,6 +73,7 @@ public class DefaultCodecRegister { |
| 71 | codecService.registerCodec(NiciraSetNshContextHeader.class, new NiciraSetNshContextHeaderCodec()); | 73 | codecService.registerCodec(NiciraSetNshContextHeader.class, new NiciraSetNshContextHeaderCodec()); |
| 72 | codecService.registerCodec(OfdpaMatchVlanVid.class, new OfdpaMatchVlanVidCodec()); | 74 | codecService.registerCodec(OfdpaMatchVlanVid.class, new OfdpaMatchVlanVidCodec()); |
| 73 | codecService.registerCodec(OfdpaSetVlanVid.class, new OfdpaSetVlanVidCodec()); | 75 | codecService.registerCodec(OfdpaSetVlanVid.class, new OfdpaSetVlanVidCodec()); |
| 76 | + codecService.registerCodec(OplinkAttenuation.class, new OplinkAttenuationCodec()); | ||
| 74 | log.info("Registered default driver codecs."); | 77 | log.info("Registered default driver codecs."); |
| 75 | } | 78 | } |
| 76 | 79 | ||
| ... | @@ -87,6 +90,7 @@ public class DefaultCodecRegister { | ... | @@ -87,6 +90,7 @@ public class DefaultCodecRegister { |
| 87 | codecService.unregisterCodec(NiciraSetNshContextHeader.class); | 90 | codecService.unregisterCodec(NiciraSetNshContextHeader.class); |
| 88 | codecService.unregisterCodec(OfdpaMatchVlanVid.class); | 91 | codecService.unregisterCodec(OfdpaMatchVlanVid.class); |
| 89 | codecService.unregisterCodec(OfdpaSetVlanVid.class); | 92 | codecService.unregisterCodec(OfdpaSetVlanVid.class); |
| 93 | + codecService.unregisterCodec(OplinkAttenuation.class); | ||
| 90 | log.info("Unregistered default driver codecs."); | 94 | log.info("Unregistered default driver codecs."); |
| 91 | } | 95 | } |
| 92 | } | 96 | } | ... | ... |
| 1 | +/* | ||
| 2 | + * Copyright 2016 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | + | ||
| 17 | +package org.onosproject.driver.extensions; | ||
| 18 | + | ||
| 19 | +import com.google.common.base.MoreObjects; | ||
| 20 | +import com.google.common.collect.Maps; | ||
| 21 | +import org.onlab.util.KryoNamespace; | ||
| 22 | +import org.onosproject.net.flow.AbstractExtension; | ||
| 23 | +import org.onosproject.net.flow.instructions.ExtensionTreatment; | ||
| 24 | +import org.onosproject.net.flow.instructions.ExtensionTreatmentType; | ||
| 25 | + | ||
| 26 | +import java.util.Map; | ||
| 27 | +import java.util.Objects; | ||
| 28 | + | ||
| 29 | +/** | ||
| 30 | + * Instruction for Oplink channel attenuation. | ||
| 31 | + */ | ||
| 32 | +public class OplinkAttenuation extends AbstractExtension implements ExtensionTreatment { | ||
| 33 | + private static final String KEY_ATT = "attenuation"; | ||
| 34 | + | ||
| 35 | + private int attenuation; | ||
| 36 | + | ||
| 37 | + private final KryoNamespace appKryo = new KryoNamespace.Builder() | ||
| 38 | + .register(Map.class) | ||
| 39 | + .build("OplinkAttenuation"); | ||
| 40 | + | ||
| 41 | + /** | ||
| 42 | + * Creates new attenuation instruction. | ||
| 43 | + * @param attenuation attenuation value | ||
| 44 | + */ | ||
| 45 | + public OplinkAttenuation(int attenuation) { | ||
| 46 | + this.attenuation = attenuation; | ||
| 47 | + } | ||
| 48 | + | ||
| 49 | + /** | ||
| 50 | + * Gets the attenuation value. | ||
| 51 | + * @return attenuation | ||
| 52 | + */ | ||
| 53 | + public int getAttenuation() { | ||
| 54 | + return attenuation; | ||
| 55 | + } | ||
| 56 | + | ||
| 57 | + /** | ||
| 58 | + * Modify the attenuation value. | ||
| 59 | + * @param attenuation new attenuation value | ||
| 60 | + */ | ||
| 61 | + public void setAttenuation(int attenuation) { | ||
| 62 | + this.attenuation = attenuation; | ||
| 63 | + } | ||
| 64 | + | ||
| 65 | + @Override | ||
| 66 | + public ExtensionTreatmentType type() { | ||
| 67 | + return ExtensionTreatmentType.ExtensionTreatmentTypes.OPLINK_ATTENUATION.type(); | ||
| 68 | + } | ||
| 69 | + | ||
| 70 | + @Override | ||
| 71 | + public byte[] serialize() { | ||
| 72 | + Map<String, Object> values = Maps.newHashMap(); | ||
| 73 | + values.put(KEY_ATT, attenuation); | ||
| 74 | + return appKryo.serialize(values); | ||
| 75 | + } | ||
| 76 | + | ||
| 77 | + @Override | ||
| 78 | + public void deserialize(byte[] data) { | ||
| 79 | + Map<String, Object> values = appKryo.deserialize(data); | ||
| 80 | + attenuation = (int) values.get(KEY_ATT); | ||
| 81 | + } | ||
| 82 | + | ||
| 83 | + @Override | ||
| 84 | + public int hashCode() { | ||
| 85 | + return Objects.hash(attenuation); | ||
| 86 | + } | ||
| 87 | + | ||
| 88 | + @Override | ||
| 89 | + public boolean equals(Object obj) { | ||
| 90 | + if (this == obj) { | ||
| 91 | + return true; | ||
| 92 | + } | ||
| 93 | + if (obj instanceof OplinkAttenuation) { | ||
| 94 | + OplinkAttenuation that = (OplinkAttenuation) obj; | ||
| 95 | + return Objects.equals(attenuation, that.attenuation); | ||
| 96 | + } | ||
| 97 | + return false; | ||
| 98 | + } | ||
| 99 | + | ||
| 100 | + @Override | ||
| 101 | + public String toString() { | ||
| 102 | + return MoreObjects.toStringHelper(getClass()) | ||
| 103 | + .add(KEY_ATT, attenuation) | ||
| 104 | + .toString(); | ||
| 105 | + } | ||
| 106 | +} |
| 1 | +/* | ||
| 2 | + * Copyright 2016 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | + | ||
| 17 | +package org.onosproject.driver.extensions; | ||
| 18 | + | ||
| 19 | +import org.onosproject.net.driver.AbstractHandlerBehaviour; | ||
| 20 | +import org.onosproject.net.flow.instructions.ExtensionTreatment; | ||
| 21 | +import org.onosproject.net.flow.instructions.ExtensionTreatmentType; | ||
| 22 | +import org.onosproject.openflow.controller.ExtensionTreatmentInterpreter; | ||
| 23 | +import org.projectfloodlight.openflow.protocol.OFActionType; | ||
| 24 | +import org.projectfloodlight.openflow.protocol.OFFactory; | ||
| 25 | +import org.projectfloodlight.openflow.protocol.action.OFAction; | ||
| 26 | +import org.projectfloodlight.openflow.protocol.action.OFActionExperimenter; | ||
| 27 | +import org.projectfloodlight.openflow.protocol.action.OFActionOplinkAtt; | ||
| 28 | +import org.projectfloodlight.openflow.protocol.oxm.OFOxm; | ||
| 29 | +import org.projectfloodlight.openflow.types.U32; | ||
| 30 | + | ||
| 31 | +/** | ||
| 32 | + * Interpreter for Oplink OpenFlow treatment extensions. | ||
| 33 | + */ | ||
| 34 | +public class OplinkExtensionTreatmentInterpreter extends AbstractHandlerBehaviour | ||
| 35 | + implements ExtensionTreatmentInterpreter { | ||
| 36 | + | ||
| 37 | + private static final long ATTENUATION_EXP = 0xff000088L; | ||
| 38 | + | ||
| 39 | + @Override | ||
| 40 | + public boolean supported(ExtensionTreatmentType extensionTreatmentType) { | ||
| 41 | + if (extensionTreatmentType.equals( | ||
| 42 | + ExtensionTreatmentType.ExtensionTreatmentTypes.OPLINK_ATTENUATION.type())) { | ||
| 43 | + return true; | ||
| 44 | + } | ||
| 45 | + return false; | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | + @Override | ||
| 49 | + public OFAction mapInstruction(OFFactory factory, ExtensionTreatment extensionTreatment) { | ||
| 50 | + ExtensionTreatmentType type = extensionTreatment.type(); | ||
| 51 | + if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OPLINK_ATTENUATION.type())) { | ||
| 52 | + int att = ((OplinkAttenuation) extensionTreatment).getAttenuation(); | ||
| 53 | + return factory.actions().oplinkAtt(factory.oxms().ochSigatt(U32.ofRaw(att))); | ||
| 54 | + } | ||
| 55 | + return null; | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | + @Override | ||
| 59 | + public ExtensionTreatment mapAction(OFAction action) throws UnsupportedOperationException { | ||
| 60 | + if (action.getType().equals(OFActionType.EXPERIMENTER)) { | ||
| 61 | + OFActionExperimenter actionExp = (OFActionExperimenter) action; | ||
| 62 | + if (actionExp.getExperimenter() == ATTENUATION_EXP) { | ||
| 63 | + OFActionOplinkAtt actionAtt = (OFActionOplinkAtt) action; | ||
| 64 | + return new OplinkAttenuation(((OFOxm<U32>) actionAtt.getField()).getValue().getRaw()); | ||
| 65 | + } | ||
| 66 | + } | ||
| 67 | + return null; | ||
| 68 | + } | ||
| 69 | +} |
drivers/default/src/main/java/org/onosproject/driver/extensions/codec/OplinkAttenuationCodec.java
0 → 100644
| 1 | +/* | ||
| 2 | + * Copyright 2016 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | + | ||
| 17 | +package org.onosproject.driver.extensions.codec; | ||
| 18 | + | ||
| 19 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
| 20 | +import org.onosproject.codec.CodecContext; | ||
| 21 | +import org.onosproject.codec.JsonCodec; | ||
| 22 | +import org.onosproject.driver.extensions.OplinkAttenuation; | ||
| 23 | + | ||
| 24 | +import static org.onlab.util.Tools.nullIsIllegal; | ||
| 25 | + | ||
| 26 | +/** | ||
| 27 | + * JSON Codec for OplinkAttenuation class. | ||
| 28 | + */ | ||
| 29 | +public class OplinkAttenuationCodec extends JsonCodec<OplinkAttenuation> { | ||
| 30 | + private static final String ATTENUATION = "attenuation"; | ||
| 31 | + private static final String MISSING_ATT = "Missing value for \"attenuation\""; | ||
| 32 | + | ||
| 33 | + @Override | ||
| 34 | + public OplinkAttenuation decode(ObjectNode json, CodecContext context) { | ||
| 35 | + if (json == null || !json.isObject()) { | ||
| 36 | + return null; | ||
| 37 | + } | ||
| 38 | + String att = nullIsIllegal(json.get(ATTENUATION), MISSING_ATT).asText(); | ||
| 39 | + return new OplinkAttenuation(Integer.valueOf(att)); | ||
| 40 | + } | ||
| 41 | +} |
| 1 | +package org.onosproject.driver.optical.extensions; | ||
| 2 | + | ||
| 3 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
| 4 | +import org.onlab.osgi.DefaultServiceDirectory; | ||
| 5 | +import org.onlab.osgi.ServiceDirectory; | ||
| 6 | +import org.onosproject.codec.CodecContext; | ||
| 7 | +import org.onosproject.codec.CodecService; | ||
| 8 | +import org.onosproject.codec.ExtensionTreatmentCodec; | ||
| 9 | +import org.onosproject.driver.extensions.OplinkAttenuation; | ||
| 10 | +import org.onosproject.net.driver.AbstractHandlerBehaviour; | ||
| 11 | +import org.onosproject.net.flow.instructions.ExtensionTreatment; | ||
| 12 | +import org.onosproject.net.flow.instructions.ExtensionTreatmentType; | ||
| 13 | + | ||
| 14 | +import static org.onlab.util.Tools.nullIsIllegal; | ||
| 15 | + | ||
| 16 | +/** | ||
| 17 | + * Codec for Oplink extensions. | ||
| 18 | + */ | ||
| 19 | +public class OplinkExtensionTreatmentCodec extends AbstractHandlerBehaviour | ||
| 20 | + implements ExtensionTreatmentCodec { | ||
| 21 | + | ||
| 22 | + private static final String TYPE = "type"; | ||
| 23 | + private static final String MISSING_TYPE = "Missing extension type"; | ||
| 24 | + private static final String UNSUPPORTED_TYPE = "Extension type is not supported: "; | ||
| 25 | + | ||
| 26 | + @Override | ||
| 27 | + public ExtensionTreatment decode(ObjectNode objectNode, CodecContext context) { | ||
| 28 | + if (objectNode == null || !objectNode.isObject()) { | ||
| 29 | + return null; | ||
| 30 | + } | ||
| 31 | + | ||
| 32 | + int typeInt = nullIsIllegal(objectNode.get(TYPE), MISSING_TYPE).asInt(); | ||
| 33 | + ExtensionTreatmentType type = new ExtensionTreatmentType(typeInt); | ||
| 34 | + | ||
| 35 | + if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OPLINK_ATTENUATION.type())) { | ||
| 36 | + return decodeTreatment(objectNode, context, OplinkAttenuation.class); | ||
| 37 | + } else { | ||
| 38 | + throw new UnsupportedOperationException(UNSUPPORTED_TYPE + type.toString()); | ||
| 39 | + } | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | + private <T extends ExtensionTreatment> ExtensionTreatment decodeTreatment( | ||
| 43 | + ObjectNode objectNode, CodecContext context, Class<T> entityClass) { | ||
| 44 | + if (context == null) { | ||
| 45 | + ServiceDirectory serviceDirectory = new DefaultServiceDirectory(); | ||
| 46 | + return serviceDirectory.get(CodecService.class).getCodec(entityClass).decode(objectNode, null); | ||
| 47 | + } else { | ||
| 48 | + return context.codec(entityClass).decode(objectNode, context); | ||
| 49 | + } | ||
| 50 | + } | ||
| 51 | +} |
drivers/optical/src/main/java/org/onosproject/driver/optical/extensions/package-info.java
0 → 100644
| 1 | +/* | ||
| 2 | + * Copyright 2016-present Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | +/** | ||
| 17 | + * Implementations of extension behaviours for optical devices. | ||
| 18 | + */ | ||
| 19 | +package org.onosproject.driver.optical.extensions; |
| ... | @@ -41,6 +41,7 @@ import org.onosproject.net.device.DefaultPortDescription; | ... | @@ -41,6 +41,7 @@ import org.onosproject.net.device.DefaultPortDescription; |
| 41 | import org.onosproject.net.device.DeviceService; | 41 | import org.onosproject.net.device.DeviceService; |
| 42 | import org.onosproject.net.device.PortDescription; | 42 | import org.onosproject.net.device.PortDescription; |
| 43 | import org.onosproject.net.link.DefaultLinkDescription; | 43 | import org.onosproject.net.link.DefaultLinkDescription; |
| 44 | +import org.onosproject.net.link.LinkService; | ||
| 44 | import org.onosproject.net.optical.OpticalAnnotations; | 45 | import org.onosproject.net.optical.OpticalAnnotations; |
| 45 | import org.onosproject.openflow.controller.Dpid; | 46 | import org.onosproject.openflow.controller.Dpid; |
| 46 | import org.onosproject.openflow.controller.OpenFlowOpticalSwitch; | 47 | import org.onosproject.openflow.controller.OpenFlowOpticalSwitch; |
| ... | @@ -190,17 +191,19 @@ public class OplinkRoadm extends AbstractOpenFlowSwitch implements OpenFlowOptic | ... | @@ -190,17 +191,19 @@ public class OplinkRoadm extends AbstractOpenFlowSwitch implements OpenFlowOptic |
| 190 | public final void sendMsg(OFMessage m) { | 191 | public final void sendMsg(OFMessage m) { |
| 191 | List<OFMessage> messages = new ArrayList<>(); | 192 | List<OFMessage> messages = new ArrayList<>(); |
| 192 | messages.add(m); | 193 | messages.add(m); |
| 194 | + | ||
| 193 | if (m.getType() == OFType.STATS_REQUEST) { | 195 | if (m.getType() == OFType.STATS_REQUEST) { |
| 194 | OFStatsRequest sr = (OFStatsRequest) m; | 196 | OFStatsRequest sr = (OFStatsRequest) m; |
| 195 | log.debug("OPLK ROADM rebuilding stats request type {}", sr.getStatsType()); | 197 | log.debug("OPLK ROADM rebuilding stats request type {}", sr.getStatsType()); |
| 196 | switch (sr.getStatsType()) { | 198 | switch (sr.getStatsType()) { |
| 197 | case PORT: | 199 | case PORT: |
| 198 | - //replace with Oplink experiment stats message to get the port current power | 200 | + //add Oplink experiment stats message to get the port's current power |
| 199 | OFOplinkPortPowerRequest powerRequest = this.factory().buildOplinkPortPowerRequest() | 201 | OFOplinkPortPowerRequest powerRequest = this.factory().buildOplinkPortPowerRequest() |
| 200 | .setXid(sr.getXid()) | 202 | .setXid(sr.getXid()) |
| 201 | .setFlags(sr.getFlags()) | 203 | .setFlags(sr.getFlags()) |
| 202 | .build(); | 204 | .build(); |
| 203 | messages.add(powerRequest); | 205 | messages.add(powerRequest); |
| 206 | + // add experiment message to get adjacent ports | ||
| 204 | OFExpPortAdjacencyRequest adjacencyRequest = this.factory().buildExpPortAdjacencyRequest() | 207 | OFExpPortAdjacencyRequest adjacencyRequest = this.factory().buildExpPortAdjacencyRequest() |
| 205 | .setXid(sr.getXid()) | 208 | .setXid(sr.getXid()) |
| 206 | .setFlags(sr.getFlags()) | 209 | .setFlags(sr.getFlags()) |
| ... | @@ -335,7 +338,7 @@ public class OplinkRoadm extends AbstractOpenFlowSwitch implements OpenFlowOptic | ... | @@ -335,7 +338,7 @@ public class OplinkRoadm extends AbstractOpenFlowSwitch implements OpenFlowOptic |
| 335 | 338 | ||
| 336 | private void addLink(PortNumber portNumber, OplinkPortAdjacency neighbor) { | 339 | private void addLink(PortNumber portNumber, OplinkPortAdjacency neighbor) { |
| 337 | ConnectPoint dst = new ConnectPoint(handler().data().deviceId(), portNumber); | 340 | ConnectPoint dst = new ConnectPoint(handler().data().deviceId(), portNumber); |
| 338 | - ConnectPoint src = new ConnectPoint(neighbor.getDeviceId(), neighbor.portNumber); | 341 | + ConnectPoint src = new ConnectPoint(neighbor.getDeviceId(), neighbor.getPort()); |
| 339 | OpticalAdjacencyLinkService adService = | 342 | OpticalAdjacencyLinkService adService = |
| 340 | this.handler().get(OpticalAdjacencyLinkService.class); | 343 | this.handler().get(OpticalAdjacencyLinkService.class); |
| 341 | adService.linkDetected(new DefaultLinkDescription(src, dst, Link.Type.OPTICAL)); | 344 | adService.linkDetected(new DefaultLinkDescription(src, dst, Link.Type.OPTICAL)); |
| ... | @@ -344,10 +347,14 @@ public class OplinkRoadm extends AbstractOpenFlowSwitch implements OpenFlowOptic | ... | @@ -344,10 +347,14 @@ public class OplinkRoadm extends AbstractOpenFlowSwitch implements OpenFlowOptic |
| 344 | // Remove incoming link with port if there are any. | 347 | // Remove incoming link with port if there are any. |
| 345 | private void removeLink(PortNumber portNumber) { | 348 | private void removeLink(PortNumber portNumber) { |
| 346 | ConnectPoint dst = new ConnectPoint(handler().data().deviceId(), portNumber); | 349 | ConnectPoint dst = new ConnectPoint(handler().data().deviceId(), portNumber); |
| 350 | + // Check so only incoming links are removed | ||
| 351 | + Set<Link> links = this.handler().get(LinkService.class).getIngressLinks(dst); | ||
| 352 | + if (!links.isEmpty()) { | ||
| 347 | OpticalAdjacencyLinkService adService = | 353 | OpticalAdjacencyLinkService adService = |
| 348 | this.handler().get(OpticalAdjacencyLinkService.class); | 354 | this.handler().get(OpticalAdjacencyLinkService.class); |
| 349 | adService.linksVanished(dst); | 355 | adService.linksVanished(dst); |
| 350 | } | 356 | } |
| 357 | + } | ||
| 351 | 358 | ||
| 352 | private class OplinkPortAdjacency { | 359 | private class OplinkPortAdjacency { |
| 353 | private DeviceId deviceId; | 360 | private DeviceId deviceId; | ... | ... |
| ... | @@ -16,14 +16,31 @@ | ... | @@ -16,14 +16,31 @@ |
| 16 | 16 | ||
| 17 | package org.onosproject.driver.optical.power; | 17 | package org.onosproject.driver.optical.power; |
| 18 | 18 | ||
| 19 | +import java.util.List; | ||
| 19 | import java.util.Optional; | 20 | import java.util.Optional; |
| 20 | 21 | ||
| 22 | +import org.onosproject.driver.extensions.OplinkAttenuation; | ||
| 23 | +import org.onosproject.net.OchSignal; | ||
| 21 | import org.onosproject.net.driver.AbstractHandlerBehaviour; | 24 | import org.onosproject.net.driver.AbstractHandlerBehaviour; |
| 22 | import org.onosproject.net.Direction; | 25 | import org.onosproject.net.Direction; |
| 23 | import org.onosproject.net.Port; | 26 | import org.onosproject.net.Port; |
| 24 | import org.onosproject.net.PortNumber; | 27 | import org.onosproject.net.PortNumber; |
| 25 | import org.onosproject.net.behaviour.PowerConfig; | 28 | import org.onosproject.net.behaviour.PowerConfig; |
| 26 | import org.onosproject.net.device.DeviceService; | 29 | import org.onosproject.net.device.DeviceService; |
| 30 | +import org.onosproject.net.flow.DefaultFlowRule; | ||
| 31 | +import org.onosproject.net.flow.DefaultTrafficTreatment; | ||
| 32 | +import org.onosproject.net.flow.FlowEntry; | ||
| 33 | +import org.onosproject.net.flow.FlowRule; | ||
| 34 | +import org.onosproject.net.flow.FlowRuleService; | ||
| 35 | +import org.onosproject.net.flow.TrafficSelector; | ||
| 36 | +import org.onosproject.net.flow.TrafficTreatment; | ||
| 37 | +import org.onosproject.net.flow.criteria.Criterion; | ||
| 38 | +import org.onosproject.net.flow.criteria.OchSignalCriterion; | ||
| 39 | +import org.onosproject.net.flow.criteria.PortCriterion; | ||
| 40 | +import org.onosproject.net.flow.instructions.ExtensionTreatment; | ||
| 41 | +import org.onosproject.net.flow.instructions.ExtensionTreatmentType; | ||
| 42 | +import org.onosproject.net.flow.instructions.Instruction; | ||
| 43 | +import org.onosproject.net.flow.instructions.Instructions; | ||
| 27 | import org.onosproject.net.optical.OpticalAnnotations; | 44 | import org.onosproject.net.optical.OpticalAnnotations; |
| 28 | import org.onosproject.openflow.controller.Dpid; | 45 | import org.onosproject.openflow.controller.Dpid; |
| 29 | import org.onosproject.openflow.controller.OpenFlowController; | 46 | import org.onosproject.openflow.controller.OpenFlowController; |
| ... | @@ -40,9 +57,28 @@ import org.slf4j.LoggerFactory; | ... | @@ -40,9 +57,28 @@ import org.slf4j.LoggerFactory; |
| 40 | */ | 57 | */ |
| 41 | 58 | ||
| 42 | public class OplinkRoadmPowerConfig extends AbstractHandlerBehaviour | 59 | public class OplinkRoadmPowerConfig extends AbstractHandlerBehaviour |
| 43 | - implements PowerConfig<Direction> { | 60 | + implements PowerConfig<Object> { |
| 61 | + | ||
| 44 | protected final Logger log = LoggerFactory.getLogger(getClass()); | 62 | protected final Logger log = LoggerFactory.getLogger(getClass()); |
| 45 | 63 | ||
| 64 | + // Component type | ||
| 65 | + private enum Type { | ||
| 66 | + NONE, | ||
| 67 | + PORT, | ||
| 68 | + CHANNEL | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + // Get the type if component is valid | ||
| 72 | + private Type getType(Object component) { | ||
| 73 | + if (component == null || component instanceof Direction) { | ||
| 74 | + return Type.PORT; | ||
| 75 | + } else if (component instanceof OchSignal) { | ||
| 76 | + return Type.CHANNEL; | ||
| 77 | + } else { | ||
| 78 | + return Type.NONE; | ||
| 79 | + } | ||
| 80 | + } | ||
| 81 | + | ||
| 46 | private OpenFlowSwitch getOpenFlowDevice() { | 82 | private OpenFlowSwitch getOpenFlowDevice() { |
| 47 | final OpenFlowController controller = this.handler().get(OpenFlowController.class); | 83 | final OpenFlowController controller = this.handler().get(OpenFlowController.class); |
| 48 | final Dpid dpid = Dpid.dpid(this.data().deviceId().uri()); | 84 | final Dpid dpid = Dpid.dpid(this.data().deviceId().uri()); |
| ... | @@ -54,41 +90,177 @@ public class OplinkRoadmPowerConfig extends AbstractHandlerBehaviour | ... | @@ -54,41 +90,177 @@ public class OplinkRoadmPowerConfig extends AbstractHandlerBehaviour |
| 54 | } | 90 | } |
| 55 | } | 91 | } |
| 56 | 92 | ||
| 93 | + // Find matching flow on device | ||
| 94 | + private FlowEntry findFlow(PortNumber portNum, OchSignal och) { | ||
| 95 | + FlowRuleService service = this.handler().get(FlowRuleService.class); | ||
| 96 | + Iterable<FlowEntry> flowEntries = service.getFlowEntries(this.data().deviceId()); | ||
| 97 | + | ||
| 98 | + // Return first matching flow | ||
| 99 | + for (FlowEntry entry : flowEntries) { | ||
| 100 | + TrafficSelector selector = entry.selector(); | ||
| 101 | + OchSignalCriterion entrySigid = | ||
| 102 | + (OchSignalCriterion) selector.getCriterion(Criterion.Type.OCH_SIGID); | ||
| 103 | + if (entrySigid != null && och.equals(entrySigid.lambda())) { | ||
| 104 | + PortCriterion entryPort = | ||
| 105 | + (PortCriterion) selector.getCriterion(Criterion.Type.IN_PORT); | ||
| 106 | + if (entryPort != null && portNum.equals(entryPort.port())) { | ||
| 107 | + return entry; | ||
| 108 | + } | ||
| 109 | + } | ||
| 110 | + } | ||
| 111 | + log.warn("No matching flow found"); | ||
| 112 | + return null; | ||
| 113 | + } | ||
| 114 | + | ||
| 57 | @Override | 115 | @Override |
| 58 | - public Optional<Long> getTargetPower(PortNumber portNum, Direction component) { | 116 | + public Optional<Long> getTargetPower(PortNumber portNum, Object component) { |
| 117 | + Long returnVal = null; | ||
| 118 | + // Check if switch is connected, otherwise do not return value in store, | ||
| 119 | + // which is obsolete. | ||
| 120 | + if (getOpenFlowDevice() != null) { | ||
| 121 | + switch (getType(component)) { | ||
| 122 | + case PORT: | ||
| 59 | // Will be implemented in the future. | 123 | // Will be implemented in the future. |
| 60 | - return Optional.empty(); | 124 | + break; |
| 125 | + case CHANNEL: | ||
| 126 | + returnVal = getChannelAttenuation(portNum, (OchSignal) component); | ||
| 127 | + break; | ||
| 128 | + default: | ||
| 129 | + break; | ||
| 130 | + } | ||
| 131 | + } | ||
| 132 | + return Optional.ofNullable(returnVal); | ||
| 61 | } | 133 | } |
| 62 | 134 | ||
| 63 | @Override | 135 | @Override |
| 64 | - public Optional<Long> currentPower(PortNumber portNum, Direction component) { | 136 | + public Optional<Long> currentPower(PortNumber portNum, Object component) { |
| 65 | Long returnVal = null; | 137 | Long returnVal = null; |
| 66 | // Check if switch is connected, otherwise do not return value in store, | 138 | // Check if switch is connected, otherwise do not return value in store, |
| 67 | // which is obsolete. | 139 | // which is obsolete. |
| 68 | if (getOpenFlowDevice() != null) { | 140 | if (getOpenFlowDevice() != null) { |
| 141 | + switch (getType(component)) { | ||
| 142 | + case PORT: | ||
| 143 | + returnVal = getCurrentPortPower(portNum); | ||
| 144 | + break; | ||
| 145 | + case CHANNEL: | ||
| 146 | + returnVal = getCurrentChannelPower(portNum, (OchSignal) component); | ||
| 147 | + break; | ||
| 148 | + default: | ||
| 149 | + break; | ||
| 150 | + } | ||
| 151 | + } | ||
| 152 | + return Optional.ofNullable(returnVal); | ||
| 153 | + } | ||
| 154 | + | ||
| 155 | + @Override | ||
| 156 | + public void setTargetPower(PortNumber portNum, Object component, long power) { | ||
| 157 | + if (getOpenFlowDevice() != null) { | ||
| 158 | + switch (getType(component)) { | ||
| 159 | + case PORT: | ||
| 160 | + setTargetPortPower(portNum, power); | ||
| 161 | + break; | ||
| 162 | + case CHANNEL: | ||
| 163 | + setChannelAttenuation(portNum, (OchSignal) component, power); | ||
| 164 | + break; | ||
| 165 | + default: | ||
| 166 | + break; | ||
| 167 | + } | ||
| 168 | + } else { | ||
| 169 | + log.warn("OpenFlow handshaker driver not found or device is not connected"); | ||
| 170 | + } | ||
| 171 | + } | ||
| 172 | + | ||
| 173 | + private Long getChannelAttenuation(PortNumber portNum, OchSignal och) { | ||
| 174 | + FlowEntry flowEntry = findFlow(portNum, och); | ||
| 175 | + if (flowEntry != null) { | ||
| 176 | + List<Instruction> instructions = flowEntry.treatment().allInstructions(); | ||
| 177 | + for (Instruction ins : instructions) { | ||
| 178 | + if (ins.type() == Instruction.Type.EXTENSION) { | ||
| 179 | + ExtensionTreatment ext = ((Instructions.ExtensionInstructionWrapper) ins).extensionInstruction(); | ||
| 180 | + if (ext.type() == ExtensionTreatmentType.ExtensionTreatmentTypes.OPLINK_ATTENUATION.type()) { | ||
| 181 | + return (long) ((OplinkAttenuation) ext).getAttenuation(); | ||
| 182 | + } | ||
| 183 | + } | ||
| 184 | + } | ||
| 185 | + } | ||
| 186 | + return null; | ||
| 187 | + } | ||
| 188 | + | ||
| 189 | + private Long getCurrentPortPower(PortNumber portNum) { | ||
| 69 | DeviceService deviceService = this.handler().get(DeviceService.class); | 190 | DeviceService deviceService = this.handler().get(DeviceService.class); |
| 70 | Port port = deviceService.getPort(this.data().deviceId(), portNum); | 191 | Port port = deviceService.getPort(this.data().deviceId(), portNum); |
| 71 | if (port != null) { | 192 | if (port != null) { |
| 72 | String currentPower = port.annotations().value(OpticalAnnotations.CURRENT_POWER); | 193 | String currentPower = port.annotations().value(OpticalAnnotations.CURRENT_POWER); |
| 73 | if (currentPower != null) { | 194 | if (currentPower != null) { |
| 74 | - returnVal = Long.valueOf(currentPower); | 195 | + return Long.valueOf(currentPower); |
| 75 | } | 196 | } |
| 76 | } | 197 | } |
| 198 | + return null; | ||
| 77 | } | 199 | } |
| 78 | - return Optional.ofNullable(returnVal); | 200 | + |
| 201 | + private Long getCurrentChannelPower(PortNumber portNum, OchSignal och) { | ||
| 202 | + FlowEntry flowEntry = findFlow(portNum, och); | ||
| 203 | + if (flowEntry != null) { | ||
| 204 | + // TODO put somewhere else if possible | ||
| 205 | + // We put channel power in packets | ||
| 206 | + return flowEntry.packets(); | ||
| 207 | + } | ||
| 208 | + return null; | ||
| 79 | } | 209 | } |
| 80 | 210 | ||
| 81 | - @Override | 211 | + private void setTargetPortPower(PortNumber portNum, long power) { |
| 82 | - public void setTargetPower(PortNumber portNum, Direction component, long power) { | ||
| 83 | OpenFlowSwitch device = getOpenFlowDevice(); | 212 | OpenFlowSwitch device = getOpenFlowDevice(); |
| 84 | - if (device != null) { | ||
| 85 | device.sendMsg(device.factory().buildOplinkPortPowerSet() | 213 | device.sendMsg(device.factory().buildOplinkPortPowerSet() |
| 86 | .setXid(0) | 214 | .setXid(0) |
| 87 | .setPort((int) portNum.toLong()) | 215 | .setPort((int) portNum.toLong()) |
| 88 | .setPowerValue((int) power) | 216 | .setPowerValue((int) power) |
| 89 | .build()); | 217 | .build()); |
| 218 | + } | ||
| 219 | + | ||
| 220 | + private void setChannelAttenuation(PortNumber portNum, OchSignal och, long power) { | ||
| 221 | + FlowEntry flowEntry = findFlow(portNum, och); | ||
| 222 | + if (flowEntry != null) { | ||
| 223 | + List<Instruction> instructions = flowEntry.treatment().allInstructions(); | ||
| 224 | + for (Instruction ins : instructions) { | ||
| 225 | + if (ins.type() == Instruction.Type.EXTENSION) { | ||
| 226 | + ExtensionTreatment ext = ((Instructions.ExtensionInstructionWrapper) ins).extensionInstruction(); | ||
| 227 | + if (ext.type() == ExtensionTreatmentType.ExtensionTreatmentTypes.OPLINK_ATTENUATION.type()) { | ||
| 228 | + ((OplinkAttenuation) ext).setAttenuation((int) power); | ||
| 229 | + FlowRuleService service = this.handler().get(FlowRuleService.class); | ||
| 230 | + service.applyFlowRules(flowEntry); | ||
| 231 | + return; | ||
| 232 | + } | ||
| 233 | + } | ||
| 234 | + } | ||
| 235 | + addAttenuation(flowEntry, power); | ||
| 90 | } else { | 236 | } else { |
| 91 | - log.warn("OpenFlow handshaker driver not found or device is not connected"); | 237 | + log.warn("Target channel power not set"); |
| 92 | } | 238 | } |
| 93 | } | 239 | } |
| 240 | + | ||
| 241 | + // Replace flow with new flow containing Oplink attenuation extension instruction. Also resets | ||
| 242 | + // metrics. | ||
| 243 | + private void addAttenuation(FlowEntry flowEntry, long power) { | ||
| 244 | + FlowRule.Builder flowBuilder = new DefaultFlowRule.Builder(); | ||
| 245 | + flowBuilder.withCookie(flowEntry.id().value()); | ||
| 246 | + flowBuilder.withPriority(flowEntry.priority()); | ||
| 247 | + flowBuilder.forDevice(flowEntry.deviceId()); | ||
| 248 | + flowBuilder.forTable(flowEntry.tableId()); | ||
| 249 | + if (flowEntry.isPermanent()) { | ||
| 250 | + flowBuilder.makePermanent(); | ||
| 251 | + } else { | ||
| 252 | + flowBuilder.makeTemporary(flowEntry.timeout()); | ||
| 253 | + } | ||
| 254 | + | ||
| 255 | + flowBuilder.withSelector(flowEntry.selector()); | ||
| 256 | + | ||
| 257 | + // Copy original instructions and add attenuation instruction | ||
| 258 | + TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder(); | ||
| 259 | + flowEntry.treatment().allInstructions().forEach(ins -> treatmentBuilder.add(ins)); | ||
| 260 | + treatmentBuilder.add(Instructions.extension(new OplinkAttenuation((int) power), this.data().deviceId())); | ||
| 261 | + flowBuilder.withTreatment(treatmentBuilder.build()); | ||
| 262 | + | ||
| 263 | + FlowRuleService service = this.handler().get(FlowRuleService.class); | ||
| 264 | + service.applyFlowRules(flowBuilder.build()); | ||
| 265 | + } | ||
| 94 | } | 266 | } | ... | ... |
| ... | @@ -58,6 +58,10 @@ | ... | @@ -58,6 +58,10 @@ |
| 58 | impl="org.onosproject.net.optical.DefaultOpticalDevice"/> | 58 | impl="org.onosproject.net.optical.DefaultOpticalDevice"/> |
| 59 | <behaviour api="org.onosproject.net.behaviour.PowerConfig" | 59 | <behaviour api="org.onosproject.net.behaviour.PowerConfig" |
| 60 | impl="org.onosproject.driver.optical.power.OplinkRoadmPowerConfig"/> | 60 | impl="org.onosproject.driver.optical.power.OplinkRoadmPowerConfig"/> |
| 61 | + <behaviour api="org.onosproject.codec.ExtensionTreatmentCodec" | ||
| 62 | + impl="org.onosproject.driver.optical.extensions.OplinkExtensionTreatmentCodec"/> | ||
| 63 | + <behaviour api="org.onosproject.openflow.controller.ExtensionTreatmentInterpreter" | ||
| 64 | + impl="org.onosproject.driver.extensions.OplinkExtensionTreatmentInterpreter"/> | ||
| 61 | </driver> | 65 | </driver> |
| 62 | 66 | ||
| 63 | </drivers> | 67 | </drivers> | ... | ... |
-
Please register or login to post a comment