(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
diff --git a/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java b/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java
index 638f00d..90f8c4e 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java
@@ -196,6 +196,21 @@
}
@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 @@
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 @@
}
@Override
+ public Builder decMplsTtl() {
+ return add(Instructions.decMplsTtl());
+ }
+
+ @Override
public Builder setLambda(short lambda) {
return add(Instructions.modL0Lambda(lambda));
}
diff --git a/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java b/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java
index e7eb85d..da682ee 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java
@@ -119,6 +119,27 @@
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 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 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
diff --git a/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java b/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java
index 4dd2c48..6f1281f 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java
@@ -28,6 +28,7 @@
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 @@
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 @@
}
/**
+ * 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 @@
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
*/
diff --git a/core/api/src/main/java/org/onosproject/net/flow/instructions/L2ModificationInstruction.java b/core/api/src/main/java/org/onosproject/net/flow/instructions/L2ModificationInstruction.java
index 6baeceb..b005bfc 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/instructions/L2ModificationInstruction.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/instructions/L2ModificationInstruction.java
@@ -65,7 +65,13 @@
/**
* 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 @@
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;
+ }
+ }
}
diff --git a/core/api/src/main/java/org/onosproject/net/flow/instructions/L3ModificationInstruction.java b/core/api/src/main/java/org/onosproject/net/flow/instructions/L3ModificationInstruction.java
index fb80557..139cc18 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/instructions/L3ModificationInstruction.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/instructions/L3ModificationInstruction.java
@@ -38,7 +38,22 @@
/**
* 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 @@
}
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;
+ }
}
}
diff --git a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowEntryBuilder.java b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowEntryBuilder.java
index a78cadb..3c1e643 100644
--- a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowEntryBuilder.java
+++ b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowEntryBuilder.java
@@ -38,8 +38,14 @@
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.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 @@
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 @@
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 @@
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 @@
case IP_ECN:
case IP_PROTO:
case METADATA:
- case MPLS_LABEL:
case MPLS_TC:
case OCH_SIGID:
case OCH_SIGID_BASIC:
diff --git a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java
index 64ebe0d..905cee9 100644
--- a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java
+++ b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java
@@ -241,8 +241,9 @@
(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 @@
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;