Steffen Gebert
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
......@@ -166,6 +166,10 @@ public abstract class ConnectivityIntentCommand extends AbstractShellCommand {
required = false, multiValued = false)
private String pushVlan = null;
@Option(name = "--setQueue", description = "Set Queue ID",
required = false, multiValued = false)
private String setQueue = null;
// Priorities
@Option(name = "-p", aliases = "--priority", description = "Priority",
required = false, multiValued = false)
......@@ -327,6 +331,10 @@ public abstract class ConnectivityIntentCommand extends AbstractShellCommand {
treatmentBuilder.setVlanId(VlanId.vlanId(Short.parseShort(pushVlan)));
emptyTreatment = false;
}
if (!isNullOrEmpty(setQueue)) {
treatmentBuilder.setQueue(Long.parseLong(setQueue));
emptyTreatment = false;
}
if (emptyTreatment) {
return DefaultTrafficTreatment.emptyTreatment();
......
......@@ -237,6 +237,7 @@ public final class DefaultTrafficTreatment implements TrafficTreatment {
case NOACTION:
case OUTPUT:
case GROUP:
case QUEUE:
case L0MODIFICATION:
case L2MODIFICATION:
case L3MODIFICATION:
......@@ -381,6 +382,11 @@ public final class DefaultTrafficTreatment implements TrafficTreatment {
}
@Override
public Builder setQueue(long queueId) {
return add(Instructions.setQueue(queueId));
}
@Override
public TrafficTreatment.Builder meter(MeterId meterId) {
return add(Instructions.meterTraffic(meterId));
}
......
......@@ -261,6 +261,14 @@ public interface TrafficTreatment {
Builder group(GroupId groupId);
/**
* Sets the Queue ID.
*
* @param queueId a queue ID
* @return a treatment builder
*/
Builder setQueue(long queueId);
/**
* Sets a meter to be used by this flow.
*
* @param meterId a meter id
......
......@@ -49,6 +49,12 @@ public interface Instruction {
GROUP,
/**
* Signifies that the traffic should be enqueued to an already-configured
queue on a port.
*/
QUEUE,
/**
* Signifies that traffic should be metered according to a meter.
*/
METER,
......
......@@ -94,6 +94,17 @@ public final class Instructions {
return new GroupInstruction(groupId);
}
/**
* Creates a set-queue instruction.
*
* @param queueId Queue Id
* @return set-queue instruction
*/
public static SetQueueInstruction setQueue(final long queueId) {
checkNotNull(queueId, "queue ID cannot be null");
return new SetQueueInstruction(queueId);
}
public static MeterInstruction meterTraffic(final MeterId meterId) {
checkNotNull(meterId, "meter id cannot be null");
return new MeterInstruction(meterId);
......@@ -625,6 +636,50 @@ public final class Instructions {
}
/**
* Set-Queue Instruction.
*/
public static final class SetQueueInstruction implements Instruction {
private final long queueId;
private SetQueueInstruction(long queueId) {
this.queueId = queueId;
}
public long queueId() {
return queueId;
}
@Override
public Type type() {
return Type.QUEUE;
}
@Override
public String toString() {
return toStringHelper(type().toString())
.add("queueId", queueId).toString();
}
@Override
public int hashCode() {
return Objects.hash(type().ordinal(), queueId);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof SetQueueInstruction) {
SetQueueInstruction that = (SetQueueInstruction) obj;
return Objects.equals(queueId, that.queueId);
}
return false;
}
}
/**
* A meter instruction.
*/
public static final class MeterInstruction implements Instruction {
......
......@@ -55,6 +55,7 @@ import org.projectfloodlight.openflow.protocol.action.OFActionCircuit;
import org.projectfloodlight.openflow.protocol.action.OFActionExperimenter;
import org.projectfloodlight.openflow.protocol.action.OFActionGroup;
import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
import org.projectfloodlight.openflow.protocol.action.OFActionSetQueue;
import org.projectfloodlight.openflow.protocol.action.OFActionPopMpls;
import org.projectfloodlight.openflow.protocol.action.OFActionSetDlDst;
import org.projectfloodlight.openflow.protocol.action.OFActionSetDlSrc;
......@@ -333,6 +334,10 @@ public class FlowEntryBuilder {
OFActionGroup group = (OFActionGroup) act;
builder.group(new DefaultGroupId(group.getGroup().getGroupNumber()));
break;
case SET_QUEUE:
OFActionSetQueue setQueue = (OFActionSetQueue) act;
builder.setQueue(setQueue.getQueueId());
break;
case STRIP_VLAN:
case POP_VLAN:
builder.popVlan();
......@@ -350,7 +355,6 @@ public class FlowEntryBuilder {
case SET_NW_ECN:
case SET_NW_TOS:
case SET_NW_TTL:
case SET_QUEUE:
case ENQUEUE:
default:
......
......@@ -26,6 +26,7 @@ import org.onosproject.net.flow.instructions.Instruction;
import org.onosproject.net.flow.instructions.Instructions;
import org.onosproject.net.flow.instructions.Instructions.GroupInstruction;
import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
import org.onosproject.net.flow.instructions.Instructions.SetQueueInstruction;
import org.onosproject.net.flow.instructions.L0ModificationInstruction;
import org.onosproject.net.flow.instructions.L0ModificationInstruction.ModLambdaInstruction;
import org.onosproject.net.flow.instructions.L0ModificationInstruction.ModOchSignalInstruction;
......@@ -50,6 +51,7 @@ import org.projectfloodlight.openflow.protocol.OFFlowModFlags;
import org.projectfloodlight.openflow.protocol.action.OFAction;
import org.projectfloodlight.openflow.protocol.action.OFActionGroup;
import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
import org.projectfloodlight.openflow.protocol.action.OFActionSetQueue;
import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
import org.projectfloodlight.openflow.protocol.match.Match;
import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
......@@ -244,6 +246,12 @@ public class FlowModBuilderVer13 extends FlowModBuilder {
.setGroup(OFGroup.of(group.groupId().id()));
actions.add(groupBuilder.build());
break;
case QUEUE:
SetQueueInstruction queue = (SetQueueInstruction) i;
OFActionSetQueue.Builder queueBuilder = factory().actions().buildSetQueue()
.setQueueId(queue.queueId());
actions.add(queueBuilder.build());
break;
case TABLE:
//FIXME: should not occur here.
tableFound = true;
......