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
Showing
6 changed files
with
67 additions
and
9 deletions
| ... | @@ -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)) { |
| 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 { | ||
| 335 | treatmentBuilder.setQueue(Long.parseLong(setQueue)); | 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 | } | ... | ... |
providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer10.java
| ... | @@ -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: | ... | ... |
-
Please register or login to post a comment