Committed by
Gerrit Code Review
Implement OFActionSetQueue (OpenFlow 1.3 only)
Action "Set-Queue" (OFPAT_SET_QUEUE) is not yet implemented. This patch adds such a QUEUE Treatment and implements it using the Set-Queue action of OpenFlow 1.3. The --setQueue parameter can be used when defining intents so that flows with the respective Set-Queue action are installed. This includes contributions by Michael Jarschel and Arne Schwabe and is the result of our ONOS Hackaton project at EWSDN 2015. Change-Id: Ie7bf01e8fd90fe68977477327ac4f53d7930e186
Showing
7 changed files
with
96 additions
and
1 deletions
| ... | @@ -166,6 +166,10 @@ public abstract class ConnectivityIntentCommand extends AbstractShellCommand { | ... | @@ -166,6 +166,10 @@ public abstract class ConnectivityIntentCommand extends AbstractShellCommand { |
| 166 | required = false, multiValued = false) | 166 | required = false, multiValued = false) |
| 167 | private String pushVlan = null; | 167 | private String pushVlan = null; |
| 168 | 168 | ||
| 169 | + @Option(name = "--setQueue", description = "Set Queue ID", | ||
| 170 | + required = false, multiValued = false) | ||
| 171 | + private String setQueue = null; | ||
| 172 | + | ||
| 169 | // Priorities | 173 | // Priorities |
| 170 | @Option(name = "-p", aliases = "--priority", description = "Priority", | 174 | @Option(name = "-p", aliases = "--priority", description = "Priority", |
| 171 | required = false, multiValued = false) | 175 | required = false, multiValued = false) |
| ... | @@ -327,6 +331,10 @@ public abstract class ConnectivityIntentCommand extends AbstractShellCommand { | ... | @@ -327,6 +331,10 @@ public abstract class ConnectivityIntentCommand extends AbstractShellCommand { |
| 327 | treatmentBuilder.setVlanId(VlanId.vlanId(Short.parseShort(pushVlan))); | 331 | treatmentBuilder.setVlanId(VlanId.vlanId(Short.parseShort(pushVlan))); |
| 328 | emptyTreatment = false; | 332 | emptyTreatment = false; |
| 329 | } | 333 | } |
| 334 | + if (!isNullOrEmpty(setQueue)) { | ||
| 335 | + treatmentBuilder.setQueue(Long.parseLong(setQueue)); | ||
| 336 | + emptyTreatment = false; | ||
| 337 | + } | ||
| 330 | 338 | ||
| 331 | if (emptyTreatment) { | 339 | if (emptyTreatment) { |
| 332 | return DefaultTrafficTreatment.emptyTreatment(); | 340 | return DefaultTrafficTreatment.emptyTreatment(); | ... | ... |
| ... | @@ -237,6 +237,7 @@ public final class DefaultTrafficTreatment implements TrafficTreatment { | ... | @@ -237,6 +237,7 @@ public final class DefaultTrafficTreatment implements TrafficTreatment { |
| 237 | case NOACTION: | 237 | case NOACTION: |
| 238 | case OUTPUT: | 238 | case OUTPUT: |
| 239 | case GROUP: | 239 | case GROUP: |
| 240 | + case QUEUE: | ||
| 240 | case L0MODIFICATION: | 241 | case L0MODIFICATION: |
| 241 | case L2MODIFICATION: | 242 | case L2MODIFICATION: |
| 242 | case L3MODIFICATION: | 243 | case L3MODIFICATION: |
| ... | @@ -381,6 +382,11 @@ public final class DefaultTrafficTreatment implements TrafficTreatment { | ... | @@ -381,6 +382,11 @@ public final class DefaultTrafficTreatment implements TrafficTreatment { |
| 381 | } | 382 | } |
| 382 | 383 | ||
| 383 | @Override | 384 | @Override |
| 385 | + public Builder setQueue(long queueId) { | ||
| 386 | + return add(Instructions.setQueue(queueId)); | ||
| 387 | + } | ||
| 388 | + | ||
| 389 | + @Override | ||
| 384 | public TrafficTreatment.Builder meter(MeterId meterId) { | 390 | public TrafficTreatment.Builder meter(MeterId meterId) { |
| 385 | return add(Instructions.meterTraffic(meterId)); | 391 | return add(Instructions.meterTraffic(meterId)); |
| 386 | } | 392 | } | ... | ... |
| ... | @@ -261,6 +261,14 @@ public interface TrafficTreatment { | ... | @@ -261,6 +261,14 @@ public interface TrafficTreatment { |
| 261 | Builder group(GroupId groupId); | 261 | Builder group(GroupId groupId); |
| 262 | 262 | ||
| 263 | /** | 263 | /** |
| 264 | + * Sets the Queue ID. | ||
| 265 | + * | ||
| 266 | + * @param queueId a queue ID | ||
| 267 | + * @return a treatment builder | ||
| 268 | + */ | ||
| 269 | + Builder setQueue(long queueId); | ||
| 270 | + | ||
| 271 | + /** | ||
| 264 | * Sets a meter to be used by this flow. | 272 | * Sets a meter to be used by this flow. |
| 265 | * | 273 | * |
| 266 | * @param meterId a meter id | 274 | * @param meterId a meter id | ... | ... |
| ... | @@ -49,6 +49,12 @@ public interface Instruction { | ... | @@ -49,6 +49,12 @@ public interface Instruction { |
| 49 | GROUP, | 49 | GROUP, |
| 50 | 50 | ||
| 51 | /** | 51 | /** |
| 52 | + * Signifies that the traffic should be enqueued to an already-configured | ||
| 53 | + queue on a port. | ||
| 54 | + */ | ||
| 55 | + QUEUE, | ||
| 56 | + | ||
| 57 | + /** | ||
| 52 | * Signifies that traffic should be metered according to a meter. | 58 | * Signifies that traffic should be metered according to a meter. |
| 53 | */ | 59 | */ |
| 54 | METER, | 60 | METER, | ... | ... |
| ... | @@ -94,6 +94,17 @@ public final class Instructions { | ... | @@ -94,6 +94,17 @@ public final class Instructions { |
| 94 | return new GroupInstruction(groupId); | 94 | return new GroupInstruction(groupId); |
| 95 | } | 95 | } |
| 96 | 96 | ||
| 97 | + /** | ||
| 98 | + * Creates a set-queue instruction. | ||
| 99 | + * | ||
| 100 | + * @param queueId Queue Id | ||
| 101 | + * @return set-queue instruction | ||
| 102 | + */ | ||
| 103 | + public static SetQueueInstruction setQueue(final long queueId) { | ||
| 104 | + checkNotNull(queueId, "queue ID cannot be null"); | ||
| 105 | + return new SetQueueInstruction(queueId); | ||
| 106 | + } | ||
| 107 | + | ||
| 97 | public static MeterInstruction meterTraffic(final MeterId meterId) { | 108 | public static MeterInstruction meterTraffic(final MeterId meterId) { |
| 98 | checkNotNull(meterId, "meter id cannot be null"); | 109 | checkNotNull(meterId, "meter id cannot be null"); |
| 99 | return new MeterInstruction(meterId); | 110 | return new MeterInstruction(meterId); |
| ... | @@ -625,6 +636,50 @@ public final class Instructions { | ... | @@ -625,6 +636,50 @@ public final class Instructions { |
| 625 | } | 636 | } |
| 626 | 637 | ||
| 627 | /** | 638 | /** |
| 639 | + * Set-Queue Instruction. | ||
| 640 | + */ | ||
| 641 | + public static final class SetQueueInstruction implements Instruction { | ||
| 642 | + private final long queueId; | ||
| 643 | + | ||
| 644 | + private SetQueueInstruction(long queueId) { | ||
| 645 | + this.queueId = queueId; | ||
| 646 | + } | ||
| 647 | + | ||
| 648 | + public long queueId() { | ||
| 649 | + return queueId; | ||
| 650 | + } | ||
| 651 | + | ||
| 652 | + @Override | ||
| 653 | + public Type type() { | ||
| 654 | + return Type.QUEUE; | ||
| 655 | + } | ||
| 656 | + | ||
| 657 | + @Override | ||
| 658 | + public String toString() { | ||
| 659 | + return toStringHelper(type().toString()) | ||
| 660 | + .add("queueId", queueId).toString(); | ||
| 661 | + } | ||
| 662 | + | ||
| 663 | + @Override | ||
| 664 | + public int hashCode() { | ||
| 665 | + return Objects.hash(type().ordinal(), queueId); | ||
| 666 | + } | ||
| 667 | + | ||
| 668 | + @Override | ||
| 669 | + public boolean equals(Object obj) { | ||
| 670 | + if (this == obj) { | ||
| 671 | + return true; | ||
| 672 | + } | ||
| 673 | + if (obj instanceof SetQueueInstruction) { | ||
| 674 | + SetQueueInstruction that = (SetQueueInstruction) obj; | ||
| 675 | + return Objects.equals(queueId, that.queueId); | ||
| 676 | + | ||
| 677 | + } | ||
| 678 | + return false; | ||
| 679 | + } | ||
| 680 | + } | ||
| 681 | + | ||
| 682 | + /** | ||
| 628 | * A meter instruction. | 683 | * A meter instruction. |
| 629 | */ | 684 | */ |
| 630 | public static final class MeterInstruction implements Instruction { | 685 | public static final class MeterInstruction implements Instruction { | ... | ... |
| ... | @@ -55,6 +55,7 @@ import org.projectfloodlight.openflow.protocol.action.OFActionCircuit; | ... | @@ -55,6 +55,7 @@ import org.projectfloodlight.openflow.protocol.action.OFActionCircuit; |
| 55 | import org.projectfloodlight.openflow.protocol.action.OFActionExperimenter; | 55 | import org.projectfloodlight.openflow.protocol.action.OFActionExperimenter; |
| 56 | import org.projectfloodlight.openflow.protocol.action.OFActionGroup; | 56 | import org.projectfloodlight.openflow.protocol.action.OFActionGroup; |
| 57 | import org.projectfloodlight.openflow.protocol.action.OFActionOutput; | 57 | import org.projectfloodlight.openflow.protocol.action.OFActionOutput; |
| 58 | +import org.projectfloodlight.openflow.protocol.action.OFActionSetQueue; | ||
| 58 | import org.projectfloodlight.openflow.protocol.action.OFActionPopMpls; | 59 | import org.projectfloodlight.openflow.protocol.action.OFActionPopMpls; |
| 59 | import org.projectfloodlight.openflow.protocol.action.OFActionSetDlDst; | 60 | import org.projectfloodlight.openflow.protocol.action.OFActionSetDlDst; |
| 60 | import org.projectfloodlight.openflow.protocol.action.OFActionSetDlSrc; | 61 | import org.projectfloodlight.openflow.protocol.action.OFActionSetDlSrc; |
| ... | @@ -333,6 +334,10 @@ public class FlowEntryBuilder { | ... | @@ -333,6 +334,10 @@ public class FlowEntryBuilder { |
| 333 | OFActionGroup group = (OFActionGroup) act; | 334 | OFActionGroup group = (OFActionGroup) act; |
| 334 | builder.group(new DefaultGroupId(group.getGroup().getGroupNumber())); | 335 | builder.group(new DefaultGroupId(group.getGroup().getGroupNumber())); |
| 335 | break; | 336 | break; |
| 337 | + case SET_QUEUE: | ||
| 338 | + OFActionSetQueue setQueue = (OFActionSetQueue) act; | ||
| 339 | + builder.setQueue(setQueue.getQueueId()); | ||
| 340 | + break; | ||
| 336 | case STRIP_VLAN: | 341 | case STRIP_VLAN: |
| 337 | case POP_VLAN: | 342 | case POP_VLAN: |
| 338 | builder.popVlan(); | 343 | builder.popVlan(); |
| ... | @@ -350,7 +355,6 @@ public class FlowEntryBuilder { | ... | @@ -350,7 +355,6 @@ public class FlowEntryBuilder { |
| 350 | case SET_NW_ECN: | 355 | case SET_NW_ECN: |
| 351 | case SET_NW_TOS: | 356 | case SET_NW_TOS: |
| 352 | case SET_NW_TTL: | 357 | case SET_NW_TTL: |
| 353 | - case SET_QUEUE: | ||
| 354 | 358 | ||
| 355 | case ENQUEUE: | 359 | case ENQUEUE: |
| 356 | default: | 360 | default: | ... | ... |
providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java
| ... | @@ -26,6 +26,7 @@ import org.onosproject.net.flow.instructions.Instruction; | ... | @@ -26,6 +26,7 @@ import org.onosproject.net.flow.instructions.Instruction; |
| 26 | import org.onosproject.net.flow.instructions.Instructions; | 26 | import org.onosproject.net.flow.instructions.Instructions; |
| 27 | import org.onosproject.net.flow.instructions.Instructions.GroupInstruction; | 27 | import org.onosproject.net.flow.instructions.Instructions.GroupInstruction; |
| 28 | import org.onosproject.net.flow.instructions.Instructions.OutputInstruction; | 28 | import org.onosproject.net.flow.instructions.Instructions.OutputInstruction; |
| 29 | +import org.onosproject.net.flow.instructions.Instructions.SetQueueInstruction; | ||
| 29 | import org.onosproject.net.flow.instructions.L0ModificationInstruction; | 30 | import org.onosproject.net.flow.instructions.L0ModificationInstruction; |
| 30 | import org.onosproject.net.flow.instructions.L0ModificationInstruction.ModLambdaInstruction; | 31 | import org.onosproject.net.flow.instructions.L0ModificationInstruction.ModLambdaInstruction; |
| 31 | import org.onosproject.net.flow.instructions.L0ModificationInstruction.ModOchSignalInstruction; | 32 | import org.onosproject.net.flow.instructions.L0ModificationInstruction.ModOchSignalInstruction; |
| ... | @@ -50,6 +51,7 @@ import org.projectfloodlight.openflow.protocol.OFFlowModFlags; | ... | @@ -50,6 +51,7 @@ import org.projectfloodlight.openflow.protocol.OFFlowModFlags; |
| 50 | import org.projectfloodlight.openflow.protocol.action.OFAction; | 51 | import org.projectfloodlight.openflow.protocol.action.OFAction; |
| 51 | import org.projectfloodlight.openflow.protocol.action.OFActionGroup; | 52 | import org.projectfloodlight.openflow.protocol.action.OFActionGroup; |
| 52 | import org.projectfloodlight.openflow.protocol.action.OFActionOutput; | 53 | import org.projectfloodlight.openflow.protocol.action.OFActionOutput; |
| 54 | +import org.projectfloodlight.openflow.protocol.action.OFActionSetQueue; | ||
| 53 | import org.projectfloodlight.openflow.protocol.instruction.OFInstruction; | 55 | import org.projectfloodlight.openflow.protocol.instruction.OFInstruction; |
| 54 | import org.projectfloodlight.openflow.protocol.match.Match; | 56 | import org.projectfloodlight.openflow.protocol.match.Match; |
| 55 | import org.projectfloodlight.openflow.protocol.oxm.OFOxm; | 57 | import org.projectfloodlight.openflow.protocol.oxm.OFOxm; |
| ... | @@ -244,6 +246,12 @@ public class FlowModBuilderVer13 extends FlowModBuilder { | ... | @@ -244,6 +246,12 @@ public class FlowModBuilderVer13 extends FlowModBuilder { |
| 244 | .setGroup(OFGroup.of(group.groupId().id())); | 246 | .setGroup(OFGroup.of(group.groupId().id())); |
| 245 | actions.add(groupBuilder.build()); | 247 | actions.add(groupBuilder.build()); |
| 246 | break; | 248 | break; |
| 249 | + case QUEUE: | ||
| 250 | + SetQueueInstruction queue = (SetQueueInstruction) i; | ||
| 251 | + OFActionSetQueue.Builder queueBuilder = factory().actions().buildSetQueue() | ||
| 252 | + .setQueueId(queue.queueId()); | ||
| 253 | + actions.add(queueBuilder.build()); | ||
| 254 | + break; | ||
| 247 | case TABLE: | 255 | case TABLE: |
| 248 | //FIXME: should not occur here. | 256 | //FIXME: should not occur here. |
| 249 | tableFound = true; | 257 | tableFound = true; | ... | ... |
-
Please register or login to post a comment