Steffen Gebert
Committed by Gerrit Code Review

Implement OFActionEnqueue (OpenFlow 1.0 only)

Realize the QUEUE Treatment using OpenFlow 1.0 Enqueue action.

The ConnectivityIntentCommand's --setQueue parameter is extended by a notion of
<port>/<queue> to support the difference from OpenFlow 1.3 Set-Queue, which is
not bound to a port.

Change-Id: I28cf70a7c004a1a3a14361e5186cfe42f09f1356
...@@ -33,6 +33,7 @@ import org.onosproject.cli.AbstractShellCommand; ...@@ -33,6 +33,7 @@ import org.onosproject.cli.AbstractShellCommand;
33 import org.onosproject.core.ApplicationId; 33 import org.onosproject.core.ApplicationId;
34 import org.onosproject.core.CoreService; 34 import org.onosproject.core.CoreService;
35 import org.onosproject.net.Link; 35 import org.onosproject.net.Link;
36 +import org.onosproject.net.PortNumber;
36 import org.onosproject.net.flow.DefaultTrafficSelector; 37 import org.onosproject.net.flow.DefaultTrafficSelector;
37 import org.onosproject.net.flow.DefaultTrafficTreatment; 38 import org.onosproject.net.flow.DefaultTrafficTreatment;
38 import org.onosproject.net.flow.TrafficSelector; 39 import org.onosproject.net.flow.TrafficSelector;
...@@ -166,7 +167,8 @@ public abstract class ConnectivityIntentCommand extends AbstractShellCommand { ...@@ -166,7 +167,8 @@ public abstract class ConnectivityIntentCommand extends AbstractShellCommand {
166 required = false, multiValued = false) 167 required = false, multiValued = false)
167 private String pushVlan = null; 168 private String pushVlan = null;
168 169
169 - @Option(name = "--setQueue", description = "Set Queue ID", 170 + @Option(name = "--setQueue", description = "Set Queue ID (for OpenFlow 1.0, " +
171 + "also the port has to be specified, i.e., <port>/<queue>",
170 required = false, multiValued = false) 172 required = false, multiValued = false)
171 private String setQueue = null; 173 private String setQueue = null;
172 174
...@@ -332,7 +334,15 @@ public abstract class ConnectivityIntentCommand extends AbstractShellCommand { ...@@ -332,7 +334,15 @@ public abstract class ConnectivityIntentCommand extends AbstractShellCommand {
332 emptyTreatment = false; 334 emptyTreatment = false;
333 } 335 }
334 if (!isNullOrEmpty(setQueue)) { 336 if (!isNullOrEmpty(setQueue)) {
335 - treatmentBuilder.setQueue(Long.parseLong(setQueue)); 337 + // OpenFlow 1.0 notation (for ENQUEUE): <port>/<queue>
338 + if (setQueue.contains("/")) {
339 + String[] queueConfig = setQueue.split("/");
340 + PortNumber port = PortNumber.portNumber(Long.parseLong(queueConfig[0]));
341 + long queueId = Long.parseLong(queueConfig[1]);
342 + treatmentBuilder.setQueue(queueId, port);
343 + } else {
344 + treatmentBuilder.setQueue(Long.parseLong(setQueue));
345 + }
336 emptyTreatment = false; 346 emptyTreatment = false;
337 } 347 }
338 348
......
...@@ -388,7 +388,12 @@ public final class DefaultTrafficTreatment implements TrafficTreatment { ...@@ -388,7 +388,12 @@ public final class DefaultTrafficTreatment implements TrafficTreatment {
388 388
389 @Override 389 @Override
390 public Builder setQueue(long queueId) { 390 public Builder setQueue(long queueId) {
391 - return add(Instructions.setQueue(queueId)); 391 + return add(Instructions.setQueue(queueId, null));
392 + }
393 +
394 + @Override
395 + public Builder setQueue(long queueId, PortNumber port) {
396 + return add(Instructions.setQueue(queueId, port));
392 } 397 }
393 398
394 @Override 399 @Override
......
...@@ -271,6 +271,15 @@ public interface TrafficTreatment { ...@@ -271,6 +271,15 @@ public interface TrafficTreatment {
271 Builder setQueue(long queueId); 271 Builder setQueue(long queueId);
272 272
273 /** 273 /**
274 + * Sets the Queue ID for a specific port.
275 + *
276 + * @param queueId a queue ID
277 + * @param port a port number
278 + * @return a treatment builder
279 + */
280 + Builder setQueue(long queueId, PortNumber port);
281 +
282 + /**
274 * Sets a meter to be used by this flow. 283 * Sets a meter to be used by this flow.
275 * 284 *
276 * @param meterId a meter id 285 * @param meterId a meter id
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
15 */ 15 */
16 package org.onosproject.net.flow.instructions; 16 package org.onosproject.net.flow.instructions;
17 17
18 +import com.google.common.base.MoreObjects;
18 import org.onlab.packet.EthType; 19 import org.onlab.packet.EthType;
19 import org.onlab.packet.IpAddress; 20 import org.onlab.packet.IpAddress;
20 import org.onlab.packet.MacAddress; 21 import org.onlab.packet.MacAddress;
...@@ -99,11 +100,12 @@ public final class Instructions { ...@@ -99,11 +100,12 @@ public final class Instructions {
99 * Creates a set-queue instruction. 100 * Creates a set-queue instruction.
100 * 101 *
101 * @param queueId Queue Id 102 * @param queueId Queue Id
103 + * @param port Port number
102 * @return set-queue instruction 104 * @return set-queue instruction
103 */ 105 */
104 - public static SetQueueInstruction setQueue(final long queueId) { 106 + public static SetQueueInstruction setQueue(final long queueId, final PortNumber port) {
105 checkNotNull(queueId, "queue ID cannot be null"); 107 checkNotNull(queueId, "queue ID cannot be null");
106 - return new SetQueueInstruction(queueId); 108 + return new SetQueueInstruction(queueId, port);
107 } 109 }
108 110
109 public static MeterInstruction meterTraffic(final MeterId meterId) { 111 public static MeterInstruction meterTraffic(final MeterId meterId) {
...@@ -655,15 +657,26 @@ public final class Instructions { ...@@ -655,15 +657,26 @@ public final class Instructions {
655 */ 657 */
656 public static final class SetQueueInstruction implements Instruction { 658 public static final class SetQueueInstruction implements Instruction {
657 private final long queueId; 659 private final long queueId;
660 + private final PortNumber port;
658 661
659 private SetQueueInstruction(long queueId) { 662 private SetQueueInstruction(long queueId) {
660 this.queueId = queueId; 663 this.queueId = queueId;
664 + this.port = null;
665 + }
666 +
667 + private SetQueueInstruction(long queueId, PortNumber port) {
668 + this.queueId = queueId;
669 + this.port = port;
661 } 670 }
662 671
663 public long queueId() { 672 public long queueId() {
664 return queueId; 673 return queueId;
665 } 674 }
666 675
676 + public PortNumber port() {
677 + return port;
678 + }
679 +
667 @Override 680 @Override
668 public Type type() { 681 public Type type() {
669 return Type.QUEUE; 682 return Type.QUEUE;
...@@ -671,13 +684,18 @@ public final class Instructions { ...@@ -671,13 +684,18 @@ public final class Instructions {
671 684
672 @Override 685 @Override
673 public String toString() { 686 public String toString() {
674 - return toStringHelper(type().toString()) 687 + MoreObjects.ToStringHelper toStringHelper = toStringHelper(type().toString());
675 - .add("queueId", queueId).toString(); 688 + toStringHelper.add("queueId", queueId);
689 +
690 + if (port() != null) {
691 + toStringHelper.add("port", port);
692 + }
693 + return toStringHelper.toString();
676 } 694 }
677 695
678 @Override 696 @Override
679 public int hashCode() { 697 public int hashCode() {
680 - return Objects.hash(type().ordinal(), queueId); 698 + return Objects.hash(type().ordinal(), queueId, port);
681 } 699 }
682 700
683 @Override 701 @Override
...@@ -687,7 +705,7 @@ public final class Instructions { ...@@ -687,7 +705,7 @@ public final class Instructions {
687 } 705 }
688 if (obj instanceof SetQueueInstruction) { 706 if (obj instanceof SetQueueInstruction) {
689 SetQueueInstruction that = (SetQueueInstruction) obj; 707 SetQueueInstruction that = (SetQueueInstruction) obj;
690 - return Objects.equals(queueId, that.queueId); 708 + return Objects.equals(queueId, that.queueId) && Objects.equals(port, that.port);
691 709
692 } 710 }
693 return false; 711 return false;
......
...@@ -50,6 +50,7 @@ import org.projectfloodlight.openflow.protocol.OFFlowRemoved; ...@@ -50,6 +50,7 @@ import org.projectfloodlight.openflow.protocol.OFFlowRemoved;
50 import org.projectfloodlight.openflow.protocol.OFFlowStatsEntry; 50 import org.projectfloodlight.openflow.protocol.OFFlowStatsEntry;
51 import org.projectfloodlight.openflow.protocol.action.OFAction; 51 import org.projectfloodlight.openflow.protocol.action.OFAction;
52 import org.projectfloodlight.openflow.protocol.action.OFActionCircuit; 52 import org.projectfloodlight.openflow.protocol.action.OFActionCircuit;
53 +import org.projectfloodlight.openflow.protocol.action.OFActionEnqueue;
53 import org.projectfloodlight.openflow.protocol.action.OFActionExperimenter; 54 import org.projectfloodlight.openflow.protocol.action.OFActionExperimenter;
54 import org.projectfloodlight.openflow.protocol.action.OFActionGroup; 55 import org.projectfloodlight.openflow.protocol.action.OFActionGroup;
55 import org.projectfloodlight.openflow.protocol.action.OFActionOutput; 56 import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
...@@ -346,6 +347,10 @@ public class FlowEntryBuilder { ...@@ -346,6 +347,10 @@ public class FlowEntryBuilder {
346 OFActionSetQueue setQueue = (OFActionSetQueue) act; 347 OFActionSetQueue setQueue = (OFActionSetQueue) act;
347 builder.setQueue(setQueue.getQueueId()); 348 builder.setQueue(setQueue.getQueueId());
348 break; 349 break;
350 + case ENQUEUE:
351 + OFActionEnqueue enqueue = (OFActionEnqueue) act;
352 + builder.setQueue(enqueue.getQueueId(), PortNumber.portNumber(enqueue.getPort().getPortNumber()));
353 + break;
349 case STRIP_VLAN: 354 case STRIP_VLAN:
350 case POP_VLAN: 355 case POP_VLAN:
351 builder.popVlan(); 356 builder.popVlan();
...@@ -364,7 +369,6 @@ public class FlowEntryBuilder { ...@@ -364,7 +369,6 @@ public class FlowEntryBuilder {
364 case SET_NW_TOS: 369 case SET_NW_TOS:
365 case SET_NW_TTL: 370 case SET_NW_TTL:
366 371
367 - case ENQUEUE:
368 default: 372 default:
369 log.warn("Action type {} not yet implemented.", act.getType()); 373 log.warn("Action type {} not yet implemented.", act.getType());
370 } 374 }
......
...@@ -22,6 +22,7 @@ import org.onosproject.net.flow.FlowRule; ...@@ -22,6 +22,7 @@ import org.onosproject.net.flow.FlowRule;
22 import org.onosproject.net.flow.TrafficTreatment; 22 import org.onosproject.net.flow.TrafficTreatment;
23 import org.onosproject.net.flow.instructions.Instruction; 23 import org.onosproject.net.flow.instructions.Instruction;
24 import org.onosproject.net.flow.instructions.Instructions.OutputInstruction; 24 import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
25 +import org.onosproject.net.flow.instructions.Instructions.SetQueueInstruction;
25 import org.onosproject.net.flow.instructions.L2ModificationInstruction; 26 import org.onosproject.net.flow.instructions.L2ModificationInstruction;
26 import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction; 27 import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
27 import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction; 28 import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
...@@ -35,6 +36,7 @@ import org.projectfloodlight.openflow.protocol.OFFlowMod; ...@@ -35,6 +36,7 @@ import org.projectfloodlight.openflow.protocol.OFFlowMod;
35 import org.projectfloodlight.openflow.protocol.OFFlowModFlags; 36 import org.projectfloodlight.openflow.protocol.OFFlowModFlags;
36 import org.projectfloodlight.openflow.protocol.action.OFAction; 37 import org.projectfloodlight.openflow.protocol.action.OFAction;
37 import org.projectfloodlight.openflow.protocol.action.OFActionOutput; 38 import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
39 +import org.projectfloodlight.openflow.protocol.action.OFActionEnqueue;
38 import org.projectfloodlight.openflow.protocol.match.Match; 40 import org.projectfloodlight.openflow.protocol.match.Match;
39 import org.projectfloodlight.openflow.types.IPv4Address; 41 import org.projectfloodlight.openflow.types.IPv4Address;
40 import org.projectfloodlight.openflow.types.MacAddress; 42 import org.projectfloodlight.openflow.types.MacAddress;
...@@ -167,6 +169,16 @@ public class FlowModBuilderVer10 extends FlowModBuilder { ...@@ -167,6 +169,16 @@ public class FlowModBuilderVer10 extends FlowModBuilder {
167 } 169 }
168 acts.add(action.build()); 170 acts.add(action.build());
169 break; 171 break;
172 + case QUEUE:
173 + SetQueueInstruction queue = (SetQueueInstruction) i;
174 + if (queue.port() == null) {
175 + log.warn("Required argument 'port' undefined for OFActionEnqueue");
176 + }
177 + OFActionEnqueue.Builder queueBuilder = factory().actions().buildEnqueue()
178 + .setQueueId(queue.queueId())
179 + .setPort(OFPort.ofInt((int) queue.port().toLong()));
180 + acts.add(queueBuilder.build());
181 + break;
170 case L0MODIFICATION: 182 case L0MODIFICATION:
171 case GROUP: 183 case GROUP:
172 case TABLE: 184 case TABLE:
......