sangho

(ONOS-684) Added a few new OF actions, which are required for Segment Routing Application

 - MPLS POP (Ethernet type)
 - Dec MPLS TTL
 - Dec NW TTL
 - Copy TTL In
 - Copy TTL Out

Change-Id: I639a1bfff9ba3ae8c372c0a4b36f132cb2610b7b
......@@ -196,6 +196,21 @@ public final class DefaultTrafficTreatment implements TrafficTreatment {
}
@Override
public Builder decNwTtl() {
return add(Instructions.decNwTtl());
}
@Override
public Builder copyTtlIn() {
return add(Instructions.copyTtlIn());
}
@Override
public Builder copyTtlOut() {
return add(Instructions.copyTtlOut());
}
@Override
public Builder pushMpls() {
return add(Instructions.pushMpls());
}
......@@ -205,6 +220,10 @@ public final class DefaultTrafficTreatment implements TrafficTreatment {
return add(Instructions.popMpls());
}
@Override
public Builder popMpls(short etherType) {
return add(Instructions.popMpls(etherType));
}
@Override
public Builder setMpls(Integer mplsLabel) {
......@@ -212,6 +231,11 @@ public final class DefaultTrafficTreatment implements TrafficTreatment {
}
@Override
public Builder decMplsTtl() {
return add(Instructions.decMplsTtl());
}
@Override
public Builder setLambda(short lambda) {
return add(Instructions.modL0Lambda(lambda));
}
......
......@@ -119,6 +119,27 @@ public interface TrafficTreatment {
public Builder setIpDst(IpAddress addr);
/**
* Decrease the TTL in IP header by one.
*
* @return a treatment builder
*/
public Builder decNwTtl();
/**
* Copy the TTL to outer protocol layer.
*
* @return a treatment builder
*/
public Builder copyTtlOut();
/**
* Copy the TTL to inner protocol layer.
*
* @return a treatment builder
*/
public Builder copyTtlIn();
/**
* Push MPLS ether type.
*
* @return a treatment builder.
......@@ -133,6 +154,14 @@ public interface TrafficTreatment {
public Builder popMpls();
/**
* Pops MPLS ether type.
*
* @param ethType Ethernet type to set
* @return a treatment builder.
*/
public Builder popMpls(short ethType);
/**
* Sets the mpls label.
*
* @param mplsLabel MPLS label.
......@@ -141,6 +170,13 @@ public interface TrafficTreatment {
public Builder setMpls(Integer mplsLabel);
/**
* Decrement MPLS TTL.
*
* @return a treatment builder
*/
public Builder decMplsTtl();
/**
* Sets the optical channel ID or lambda.
*
* @param lambda optical channel ID
......
......@@ -28,6 +28,7 @@ import org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType
import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
import org.onosproject.net.flow.instructions.L3ModificationInstruction.L3SubType;
import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModTtlInstruction;
import org.onlab.packet.Ethernet;
import org.onlab.packet.IpAddress;
......@@ -122,6 +123,15 @@ public final class Instructions {
checkNotNull(mplsLabel, "MPLS label cannot be null");
return new ModMplsLabelInstruction(mplsLabel);
}
/**
* Creates a MPLS TTL modification.
*
* @return a L2 Modification
*/
public static L2ModificationInstruction decMplsTtl() {
return new ModMplsTtlInstruction();
}
/**
* Creates a L3 src modification.
* @param addr the ip address to modify to.
......@@ -143,6 +153,30 @@ public final class Instructions {
}
/**
* Creates a L3 TTL modification.
* @return a L3 modification
*/
public static L3ModificationInstruction decNwTtl() {
return new ModTtlInstruction(L3SubType.DEC_TTL);
}
/**
* Creates a L3 TTL modification.
* @return a L3 modification
*/
public static L3ModificationInstruction copyTtlOut() {
return new ModTtlInstruction(L3SubType.TTL_OUT);
}
/**
* Creates a L3 TTL modification.
* @return a L3 modification
*/
public static L3ModificationInstruction copyTtlIn() {
return new ModTtlInstruction(L3SubType.TTL_IN);
}
/**
* Creates a mpls header instruction.
* @return a L2 modification.
*/
......@@ -160,6 +194,18 @@ public final class Instructions {
new Ethernet().setEtherType(Ethernet.MPLS_UNICAST));
}
/**
* Creates a mpls header instruction.
*
* @param etherType Ethernet type to set
* @return a L2 modification.
*/
public static Instruction popMpls(Short etherType) {
checkNotNull(etherType, "Ethernet type cannot be null");
return new PushHeaderInstructions(L2SubType.MPLS_POP,
new Ethernet().setEtherType(etherType));
}
/*
* Output instructions
*/
......
......@@ -65,7 +65,13 @@ public abstract class L2ModificationInstruction implements Instruction {
/**
* MPLS Pop modification.
*/
MPLS_POP
MPLS_POP,
/**
* MPLS TTL modification.
*/
DEC_MPLS_TTL
}
// TODO: Create factory class 'Instructions' that will have various factory
......@@ -322,4 +328,41 @@ public abstract class L2ModificationInstruction implements Instruction {
return false;
}
}
/**
* Represents a MPLS label modification.
*/
public static final class ModMplsTtlInstruction extends
L2ModificationInstruction {
public ModMplsTtlInstruction() {
}
@Override
public L2SubType subtype() {
return L2SubType.DEC_MPLS_TTL;
}
@Override
public String toString() {
return type().toString();
}
@Override
public int hashCode() {
return Objects.hash(type(), L2SubType.DEC_MPLS_TTL);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof ModMplsLabelInstruction) {
ModMplsTtlInstruction that = (ModMplsTtlInstruction) obj;
return Objects.equals(this.type(), that.type());
}
return false;
}
}
}
......
......@@ -38,7 +38,22 @@ public abstract class L3ModificationInstruction implements Instruction {
/**
* Ether dst modification.
*/
IP_DST
IP_DST,
/**
* Decrease TTL.
*/
DEC_TTL,
/**
* Copy TTL out.
*/
TTL_OUT,
/**
* Copy TTL in.
*/
TTL_IN
//TODO: remaining types
}
......@@ -102,6 +117,43 @@ public abstract class L3ModificationInstruction implements Instruction {
}
return false;
}
}
public static final class ModTtlInstruction extends L3ModificationInstruction {
private final L3SubType subtype;
public ModTtlInstruction(L3SubType subtype) {
this.subtype = subtype;
}
@Override
public L3SubType subtype() {
return this.subtype;
}
@Override
public String toString() {
return subtype().toString();
}
@Override
public int hashCode() {
return Objects.hash(type(), subtype());
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof ModIPInstruction) {
ModIPInstruction that = (ModIPInstruction) obj;
return Objects.equals(this.type(), that.type()) &&
Objects.equals(this.subtype(), that.subtype());
}
return false;
}
}
}
......
......@@ -38,8 +38,14 @@ import org.projectfloodlight.openflow.protocol.OFFlowStatsEntry;
import org.projectfloodlight.openflow.protocol.OFInstructionType;
import org.projectfloodlight.openflow.protocol.action.OFAction;
import org.projectfloodlight.openflow.protocol.action.OFActionCircuit;
import org.projectfloodlight.openflow.protocol.action.OFActionCopyTtlIn;
import org.projectfloodlight.openflow.protocol.action.OFActionCopyTtlOut;
import org.projectfloodlight.openflow.protocol.action.OFActionDecMplsTtl;
import org.projectfloodlight.openflow.protocol.action.OFActionDecNwTtl;
import org.projectfloodlight.openflow.protocol.action.OFActionExperimenter;
import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
import org.projectfloodlight.openflow.protocol.action.OFActionPopMpls;
import org.projectfloodlight.openflow.protocol.action.OFActionPushMpls;
import org.projectfloodlight.openflow.protocol.action.OFActionSetDlDst;
import org.projectfloodlight.openflow.protocol.action.OFActionSetDlSrc;
import org.projectfloodlight.openflow.protocol.action.OFActionSetField;
......@@ -57,6 +63,7 @@ import org.projectfloodlight.openflow.types.IPv4Address;
import org.projectfloodlight.openflow.types.IPv6Address;
import org.projectfloodlight.openflow.types.Masked;
import org.projectfloodlight.openflow.types.OFVlanVidMatch;
import org.projectfloodlight.openflow.types.U32;
import org.projectfloodlight.openflow.types.VlanPcp;
import org.slf4j.Logger;
......@@ -194,12 +201,34 @@ public class FlowEntryBuilder {
OFActionSetField setField = (OFActionSetField) act;
handleSetField(builder, setField.getField());
break;
case POP_MPLS:
OFActionPopMpls popMpls = (OFActionPopMpls) act;
builder.popMpls((short) popMpls.getEthertype().getValue());
break;
case PUSH_MPLS:
OFActionPushMpls pushMpls = (OFActionPushMpls) act;
builder.pushMpls();
break;
case COPY_TTL_IN:
OFActionCopyTtlIn copyTtlIn = (OFActionCopyTtlIn) act;
builder.copyTtlIn();
break;
case COPY_TTL_OUT:
OFActionCopyTtlOut copyTtlOut = (OFActionCopyTtlOut) act;
builder.copyTtlOut();
break;
case DEC_MPLS_TTL:
OFActionDecMplsTtl decMplsTtl = (OFActionDecMplsTtl) act;
builder.decMplsTtl();
break;
case DEC_NW_TTL:
OFActionDecNwTtl decNwTtl = (OFActionDecNwTtl) act;
builder.decNwTtl();
break;
case SET_TP_DST:
case SET_TP_SRC:
case POP_MPLS:
case POP_PBB:
case POP_VLAN:
case PUSH_MPLS:
case PUSH_PBB:
case PUSH_VLAN:
case SET_MPLS_LABEL:
......@@ -210,10 +239,6 @@ public class FlowEntryBuilder {
case SET_NW_TTL:
case SET_QUEUE:
case STRIP_VLAN:
case COPY_TTL_IN:
case COPY_TTL_OUT:
case DEC_MPLS_TTL:
case DEC_NW_TTL:
case ENQUEUE:
case GROUP:
......@@ -259,6 +284,11 @@ public class FlowEntryBuilder {
OFOxm<IPv4Address> ip4src = (OFOxm<IPv4Address>) oxm;
builder.setIpSrc(Ip4Address.valueOf(ip4src.getValue().getInt()));
break;
case MPLS_LABEL:
@SuppressWarnings("unchecked")
OFOxm<U32> labelId = (OFOxm<U32>) oxm;
builder.setMpls((int) labelId.getValue().getValue());
break;
case ARP_OP:
case ARP_SHA:
case ARP_SPA:
......@@ -299,7 +329,6 @@ public class FlowEntryBuilder {
case IP_ECN:
case IP_PROTO:
case METADATA:
case MPLS_LABEL:
case MPLS_TC:
case OCH_SIGID:
case OCH_SIGID_BASIC:
......
......@@ -241,8 +241,9 @@ public class FlowModBuilderVer13 extends FlowModBuilder {
(ModMplsLabelInstruction) l2m;
oxm = factory().oxms().mplsLabel(U32.of(mplsLabel.label()
.longValue()));
break;
case DEC_MPLS_TTL:
return factory().actions().decMplsTtl();
default:
log.warn("Unimplemented action type {}.", l2m.subtype());
break;
......@@ -270,6 +271,12 @@ public class FlowModBuilderVer13 extends FlowModBuilder {
ip4 = ip.ip().getIp4Address();
oxm = factory().oxms().ipv4Src(IPv4Address.of(ip4.toInt()));
break;
case DEC_TTL:
return factory().actions().decNwTtl();
case TTL_IN:
return factory().actions().copyTtlIn();
case TTL_OUT:
return factory().actions().copyTtlOut();
default:
log.warn("Unimplemented action type {}.", l3m.subtype());
break;
......