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