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