Implement some of the missing IPv6 flowmod treatments
Work toward ONOS-509
The following treatments are added/implemented:
- IPV6_SRC
- IPV6_DST
- IPV6_FLABEL
Also:
- Renamed L3ModificationInstruction.L3SubType.IP_SRC and IP_DST
to IPV4_SRC and IPV4_DST (for naming consistency).
- Few minor fixes in related code: Javadocs, comments, log messages,
and IP address usage.
Change-Id: I551056f767a37e7cb6ae7d79f4a3929183500b57
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 91edcbf..98cb3b2 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
@@ -120,7 +120,7 @@
public Builder setIpDst(IpAddress addr);
/**
- * Decrease the TTL in IP header by one.
+ * Decrement the TTL in IP header by one.
*
* @return a treatment builder
*/
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 8141c9a..3838cdf 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
@@ -29,6 +29,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.ModIPv6FlowLabelInstruction;
import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModTtlInstruction;
import org.onlab.packet.Ethernet;
@@ -144,24 +145,59 @@
public static L2ModificationInstruction decMplsTtl() {
return new ModMplsTtlInstruction();
}
+
/**
- * Creates a L3 src modification.
- * @param addr the ip address to modify to.
+ * Creates a L3 IPv4 src modification.
+ *
+ * @param addr the IPv4 address to modify to
* @return a L3 modification
*/
public static L3ModificationInstruction modL3Src(IpAddress addr) {
- checkNotNull(addr, "Src l3 address cannot be null");
- return new ModIPInstruction(L3SubType.IP_SRC, addr);
+ checkNotNull(addr, "Src l3 IPv4 address cannot be null");
+ return new ModIPInstruction(L3SubType.IPV4_SRC, addr);
}
/**
- * Creates a L3 dst modification.
- * @param addr the ip address to modify to.
+ * Creates a L3 IPv4 dst modification.
+ *
+ * @param addr the IPv4 address to modify to
* @return a L3 modification
*/
public static L3ModificationInstruction modL3Dst(IpAddress addr) {
- checkNotNull(addr, "Dst l3 address cannot be null");
- return new ModIPInstruction(L3SubType.IP_DST, addr);
+ checkNotNull(addr, "Dst l3 IPv4 address cannot be null");
+ return new ModIPInstruction(L3SubType.IPV4_DST, addr);
+ }
+
+ /**
+ * Creates a L3 IPv6 src modification.
+ *
+ * @param addr the IPv6 address to modify to
+ * @return a L3 modification
+ */
+ public static L3ModificationInstruction modL3IPv6Src(IpAddress addr) {
+ checkNotNull(addr, "Src l3 IPv6 address cannot be null");
+ return new ModIPInstruction(L3SubType.IPV6_SRC, addr);
+ }
+
+ /**
+ * Creates a L3 IPv6 dst modification.
+ *
+ * @param addr the IPv6 address to modify to
+ * @return a L3 modification
+ */
+ public static L3ModificationInstruction modL3IPv6Dst(IpAddress addr) {
+ checkNotNull(addr, "Dst l3 IPv6 address cannot be null");
+ return new ModIPInstruction(L3SubType.IPV6_DST, addr);
+ }
+
+ /**
+ * Creates a L3 IPv6 Flow Label modification.
+ *
+ * @param flowLabel the IPv6 flow label to modify to (20 bits)
+ * @return a L3 modification
+ */
+ public static L3ModificationInstruction modL3IPv6FlowLabel(int flowLabel) {
+ return new ModIPv6FlowLabelInstruction(flowLabel);
}
/**
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 93e85ef..f8814a0 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
@@ -31,17 +31,32 @@
*/
public enum L3SubType {
/**
- * Ether src modification.
+ * IPv4 src modification.
*/
- IP_SRC,
+ IPV4_SRC,
/**
- * Ether dst modification.
+ * IPv4 dst modification.
*/
- IP_DST,
+ IPV4_DST,
/**
- * Decrease TTL.
+ * IPv6 src modification.
+ */
+ IPV6_SRC,
+
+ /**
+ * IPv6 dst modification.
+ */
+ IPV6_DST,
+
+ /**
+ * IPv6 flow label modification.
+ */
+ IPV6_FLABEL,
+
+ /**
+ * Decrement TTL.
*/
DEC_TTL,
@@ -120,6 +135,65 @@
}
/**
+ * Represents a L3 IPv6 Flow Label (RFC 6437) modification instruction
+ * (20 bits unsigned integer).
+ */
+ public static final class ModIPv6FlowLabelInstruction
+ extends L3ModificationInstruction {
+ private static final int MASK = 0xfffff;
+ private final int flowLabel; // IPv6 flow label: 20 bits
+
+ /**
+ * Constructor.
+ *
+ * flowLabel the IPv6 flow label to set in the treatment (20 bits)
+ */
+ public ModIPv6FlowLabelInstruction(int flowLabel) {
+ this.flowLabel = flowLabel & MASK;
+ }
+
+ @Override
+ public L3SubType subtype() {
+ return L3SubType.IPV6_FLABEL;
+ }
+
+ /**
+ * Gets the IPv6 flow label to set in the treatment.
+ *
+ * @return the IPv6 flow label to set in the treatment (20 bits)
+ */
+ public int flowLabel() {
+ return this.flowLabel;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(subtype().toString())
+ .add("flowLabel", Long.toHexString(flowLabel)).toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(type(), subtype(), flowLabel);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof ModIPv6FlowLabelInstruction) {
+ ModIPv6FlowLabelInstruction that =
+ (ModIPv6FlowLabelInstruction) obj;
+ return Objects.equals(flowLabel, that.flowLabel) &&
+ Objects.equals(this.type(), that.type()) &&
+ Objects.equals(this.subtype(), that.subtype());
+ }
+ return false;
+ }
+ }
+
+ /**
* Represents a L3 TTL modification instruction.
*/
public static final class ModTtlInstruction extends L3ModificationInstruction {
diff --git a/core/api/src/test/java/org/onosproject/net/flow/instructions/InstructionsTest.java b/core/api/src/test/java/org/onosproject/net/flow/instructions/InstructionsTest.java
index d8b511c..bfb8409 100644
--- a/core/api/src/test/java/org/onosproject/net/flow/instructions/InstructionsTest.java
+++ b/core/api/src/test/java/org/onosproject/net/flow/instructions/InstructionsTest.java
@@ -18,7 +18,6 @@
import org.junit.Test;
import org.onosproject.net.PortNumber;
import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
@@ -94,6 +93,7 @@
assertThatClassIsImmutable(L2ModificationInstruction.ModVlanIdInstruction.class);
assertThatClassIsImmutable(L2ModificationInstruction.ModVlanPcpInstruction.class);
assertThatClassIsImmutable(L3ModificationInstruction.ModIPInstruction.class);
+ assertThatClassIsImmutable(L3ModificationInstruction.ModIPv6FlowLabelInstruction.class);
assertThatClassIsImmutable(L2ModificationInstruction.ModMplsLabelInstruction.class);
assertThatClassIsImmutable(L2ModificationInstruction.PushHeaderInstructions.class);
}
@@ -377,29 +377,40 @@
is(not(equalTo(modVlanPcp2.hashCode()))));
}
- // ModIPerInstruction
+ // ModIPInstruction
- private static final String IP1 = "1.2.3.4/24";
- private static final String IP2 = "5.6.7.8/24";
- private IpAddress ip1 = IpPrefix.valueOf(IP1).address();
- private IpAddress ip2 = IpPrefix.valueOf(IP2).address();
- private final Instruction modIPInstruction1 = Instructions.modL3Src(ip1);
- private final Instruction sameAsModIPInstruction1 = Instructions.modL3Src(ip1);
- private final Instruction modIPInstruction2 = Instructions.modL3Src(ip2);
+ private static final String IP41 = "1.2.3.4";
+ private static final String IP42 = "5.6.7.8";
+ private IpAddress ip41 = IpAddress.valueOf(IP41);
+ private IpAddress ip42 = IpAddress.valueOf(IP42);
+ private final Instruction modIPInstruction1 = Instructions.modL3Src(ip41);
+ private final Instruction sameAsModIPInstruction1 = Instructions.modL3Src(ip41);
+ private final Instruction modIPInstruction2 = Instructions.modL3Src(ip42);
+
+ private static final String IP61 = "1111::2222";
+ private static final String IP62 = "3333::4444";
+ private IpAddress ip61 = IpAddress.valueOf(IP61);
+ private IpAddress ip62 = IpAddress.valueOf(IP62);
+ private final Instruction modIPv6Instruction1 =
+ Instructions.modL3IPv6Src(ip61);
+ private final Instruction sameAsModIPv6Instruction1 =
+ Instructions.modL3IPv6Src(ip61);
+ private final Instruction modIPv6Instruction2 =
+ Instructions.modL3IPv6Src(ip62);
/**
* Test the modL3Src method.
*/
@Test
public void testModL3SrcMethod() {
- final Instruction instruction = Instructions.modL3Src(ip1);
+ final Instruction instruction = Instructions.modL3Src(ip41);
final L3ModificationInstruction.ModIPInstruction modIPInstruction =
checkAndConvert(instruction,
Instruction.Type.L3MODIFICATION,
L3ModificationInstruction.ModIPInstruction.class);
- assertThat(modIPInstruction.ip(), is(equalTo(ip1)));
+ assertThat(modIPInstruction.ip(), is(equalTo(ip41)));
assertThat(modIPInstruction.subtype(),
- is(equalTo(L3ModificationInstruction.L3SubType.IP_SRC)));
+ is(equalTo(L3ModificationInstruction.L3SubType.IPV4_SRC)));
}
/**
@@ -407,20 +418,49 @@
*/
@Test
public void testModL3DstMethod() {
- final Instruction instruction = Instructions.modL3Dst(ip1);
+ final Instruction instruction = Instructions.modL3Dst(ip41);
final L3ModificationInstruction.ModIPInstruction modIPInstruction =
checkAndConvert(instruction,
Instruction.Type.L3MODIFICATION,
L3ModificationInstruction.ModIPInstruction.class);
- assertThat(modIPInstruction.ip(), is(equalTo(ip1)));
+ assertThat(modIPInstruction.ip(), is(equalTo(ip41)));
assertThat(modIPInstruction.subtype(),
- is(equalTo(L3ModificationInstruction.L3SubType.IP_DST)));
+ is(equalTo(L3ModificationInstruction.L3SubType.IPV4_DST)));
}
/**
- * Test the equals() method of the ModEtherInstruction class.
+ * Test the modL3IPv6Src method.
*/
+ @Test
+ public void testModL3IPv6SrcMethod() {
+ final Instruction instruction = Instructions.modL3IPv6Src(ip61);
+ final L3ModificationInstruction.ModIPInstruction modIPInstruction =
+ checkAndConvert(instruction,
+ Instruction.Type.L3MODIFICATION,
+ L3ModificationInstruction.ModIPInstruction.class);
+ assertThat(modIPInstruction.ip(), is(equalTo(ip61)));
+ assertThat(modIPInstruction.subtype(),
+ is(equalTo(L3ModificationInstruction.L3SubType.IPV6_SRC)));
+ }
+ /**
+ * Test the modL3IPv6Dst method.
+ */
+ @Test
+ public void testModL3IPv6DstMethod() {
+ final Instruction instruction = Instructions.modL3IPv6Dst(ip61);
+ final L3ModificationInstruction.ModIPInstruction modIPInstruction =
+ checkAndConvert(instruction,
+ Instruction.Type.L3MODIFICATION,
+ L3ModificationInstruction.ModIPInstruction.class);
+ assertThat(modIPInstruction.ip(), is(equalTo(ip61)));
+ assertThat(modIPInstruction.subtype(),
+ is(equalTo(L3ModificationInstruction.L3SubType.IPV6_DST)));
+ }
+
+ /**
+ * Test the equals() method of the ModIPInstruction class.
+ */
@Test
public void testModIPInstructionEquals() throws Exception {
checkEqualsAndToString(modIPInstruction1,
@@ -429,9 +469,8 @@
}
/**
- * Test the hashCode() method of the ModEtherInstruction class.
+ * Test the hashCode() method of the ModIPInstruction class.
*/
-
@Test
public void testModIPInstructionHashCode() {
assertThat(modIPInstruction1.hashCode(),
@@ -440,6 +479,54 @@
is(not(equalTo(modIPInstruction2.hashCode()))));
}
+ private final int flowLabel1 = 0x11111;
+ private final int flowLabel2 = 0x22222;
+ private final Instruction modIPv6FlowLabelInstruction1 =
+ Instructions.modL3IPv6FlowLabel(flowLabel1);
+ private final Instruction sameAsModIPv6FlowLabelInstruction1 =
+ Instructions.modL3IPv6FlowLabel(flowLabel1);
+ private final Instruction modIPv6FlowLabelInstruction2 =
+ Instructions.modL3IPv6FlowLabel(flowLabel2);
+
+ /**
+ * Test the modL3IPv6FlowLabel method.
+ */
+ @Test
+ public void testModL3IPv6FlowLabelMethod() {
+ final Instruction instruction =
+ Instructions.modL3IPv6FlowLabel(flowLabel1);
+ final L3ModificationInstruction.ModIPv6FlowLabelInstruction
+ modIPv6FlowLabelInstruction =
+ checkAndConvert(instruction,
+ Instruction.Type.L3MODIFICATION,
+ L3ModificationInstruction.ModIPv6FlowLabelInstruction.class);
+ assertThat(modIPv6FlowLabelInstruction.flowLabel(),
+ is(equalTo(flowLabel1)));
+ assertThat(modIPv6FlowLabelInstruction.subtype(),
+ is(equalTo(L3ModificationInstruction.L3SubType.IPV6_FLABEL)));
+ }
+
+ /**
+ * Test the equals() method of the ModIPv6FlowLabelInstruction class.
+ */
+ @Test
+ public void testModIPv6FlowLabelInstructionEquals() throws Exception {
+ checkEqualsAndToString(modIPv6FlowLabelInstruction1,
+ sameAsModIPv6FlowLabelInstruction1,
+ modIPv6FlowLabelInstruction2);
+ }
+
+ /**
+ * Test the hashCode() method of the ModIPv6FlowLabelInstruction class.
+ */
+ @Test
+ public void testModIPv6FlowLabelInstructionHashCode() {
+ assertThat(modIPv6FlowLabelInstruction1.hashCode(),
+ is(equalTo(sameAsModIPv6FlowLabelInstruction1.hashCode())));
+ assertThat(modIPv6FlowLabelInstruction1.hashCode(),
+ is(not(equalTo(modIPv6FlowLabelInstruction2.hashCode()))));
+ }
+
private Instruction modMplsLabelInstruction1 = Instructions.modMplsLabel(1);
private Instruction sameAsModMplsLabelInstruction1 = Instructions.modMplsLabel(1);
private Instruction modMplsLabelInstruction2 = Instructions.modMplsLabel(2);
@@ -463,7 +550,6 @@
* Test the equals(), hashCode and toString() methods of the
* ModMplsLabelInstruction class.
*/
-
@Test
public void testModMplsLabelInstructionEquals() throws Exception {
checkEqualsAndToString(modMplsLabelInstruction1,