Hyunsun Moon
Committed by Gerrit Code Review

ONOS-2578 Added codec for mod tcp/udp port instructions

Change-Id: Iab1eac26afe47e0b1c13ce94e152826b0828e455
......@@ -18,19 +18,21 @@ package org.onosproject.codec.impl;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.packet.MplsLabel;
import org.onlab.packet.TpPort;
import org.onlab.packet.VlanId;
import org.onosproject.net.ChannelSpacing;
import org.onosproject.net.GridType;
import org.onosproject.net.Lambda;
import org.onosproject.net.OchSignal;
import org.onosproject.net.PortNumber;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onosproject.net.flow.instructions.Instruction;
import org.onosproject.net.flow.instructions.Instructions;
import org.onosproject.net.flow.instructions.L0ModificationInstruction;
import org.onosproject.net.flow.instructions.L2ModificationInstruction;
import org.onosproject.net.flow.instructions.L3ModificationInstruction;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onosproject.net.flow.instructions.L4ModificationInstruction;
import static org.onlab.util.Tools.nullIsIllegal;
......@@ -172,6 +174,36 @@ public final class DecodeInstructionCodecHelper {
}
/**
* Decodes a Layer 4 instruction.
*
* @return instruction object decoded from the JSON
* @throws IllegalArgumentException if the JSON is invalid
*/
private Instruction decodeL4() {
String subType = json.get(InstructionCodec.SUBTYPE).asText();
if (subType.equals(L4ModificationInstruction.L4SubType.TCP_DST.name())) {
TpPort tcpPort = TpPort.tpPort(nullIsIllegal(json.get(InstructionCodec.TCP_PORT),
InstructionCodec.TCP_PORT + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt());
return Instructions.modTcpDst(tcpPort);
} else if (subType.equals(L4ModificationInstruction.L4SubType.TCP_SRC.name())) {
TpPort tcpPort = TpPort.tpPort(nullIsIllegal(json.get(InstructionCodec.TCP_PORT),
InstructionCodec.TCP_PORT + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt());
return Instructions.modTcpSrc(tcpPort);
} else if (subType.equals(L4ModificationInstruction.L4SubType.UDP_DST.name())) {
TpPort udpPort = TpPort.tpPort(nullIsIllegal(json.get(InstructionCodec.UDP_PORT),
InstructionCodec.UDP_PORT + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt());
return Instructions.modUdpDst(udpPort);
} else if (subType.equals(L4ModificationInstruction.L4SubType.UDP_SRC.name())) {
TpPort udpPort = TpPort.tpPort(nullIsIllegal(json.get(InstructionCodec.UDP_PORT),
InstructionCodec.UDP_PORT + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt());
return Instructions.modUdpSrc(udpPort);
}
throw new IllegalArgumentException("L4 Instruction subtype "
+ subType + " is not supported");
}
/**
* Decodes the JSON into an instruction object.
*
* @return Criterion object
......@@ -193,6 +225,8 @@ public final class DecodeInstructionCodecHelper {
return decodeL2();
} else if (type.equals(Instruction.Type.L3MODIFICATION.name())) {
return decodeL3();
} else if (type.equals(Instruction.Type.L4MODIFICATION.name())) {
return decodeL4();
}
throw new IllegalArgumentException("Instruction type "
+ type + " is not supported");
......
......@@ -22,6 +22,7 @@ import org.onosproject.net.flow.instructions.Instructions;
import org.onosproject.net.flow.instructions.L0ModificationInstruction;
import org.onosproject.net.flow.instructions.L2ModificationInstruction;
import org.onosproject.net.flow.instructions.L3ModificationInstruction;
import org.onosproject.net.flow.instructions.L4ModificationInstruction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -168,6 +169,36 @@ public final class EncodeInstructionCodecHelper {
}
/**
* Encode a L4 modification instruction.
*
* @param result json node that the instruction attributes are added to
*/
private void encodeL4(ObjectNode result) {
L4ModificationInstruction instruction =
(L4ModificationInstruction) this.instruction;
result.put(InstructionCodec.SUBTYPE, instruction.subtype().name());
switch (instruction.subtype()) {
case TCP_DST:
case TCP_SRC:
final L4ModificationInstruction.ModTransportPortInstruction modTcpPortInstruction =
(L4ModificationInstruction.ModTransportPortInstruction) instruction;
result.put(InstructionCodec.TCP_PORT, modTcpPortInstruction.port().toInt());
break;
case UDP_DST:
case UDP_SRC:
final L4ModificationInstruction.ModTransportPortInstruction modUdpPortInstruction =
(L4ModificationInstruction.ModTransportPortInstruction) instruction;
result.put(InstructionCodec.UDP_PORT, modUdpPortInstruction.port().toInt());
break;
default:
log.info("Cannot convert L4 subtype of {}", instruction.subtype());
break;
}
}
/**
* Encodes the given instruction into JSON.
*
* @return JSON object node representing the instruction
......@@ -198,6 +229,10 @@ public final class EncodeInstructionCodecHelper {
encodeL3(result);
break;
case L4MODIFICATION:
encodeL4(result);
break;
default:
log.info("Cannot convert instruction type of {}", instruction.type());
break;
......
......@@ -48,6 +48,8 @@ public final class InstructionCodec extends JsonCodec<Instruction> {
protected static final String SLOT_GRANULARITY = "slotGranularity";
protected static final String ETHERNET_TYPE = "ethernetType";
protected static final String TUNNEL_ID = "tunnelId";
protected static final String TCP_PORT = "tcpPort";
protected static final String UDP_PORT = "udpPort";
protected static final String MISSING_MEMBER_MESSAGE =
" member is required in Instruction";
......
......@@ -62,14 +62,15 @@ import org.onosproject.net.flow.criteria.TunnelIdCriterion;
import org.onosproject.net.flow.criteria.UdpPortCriterion;
import org.onosproject.net.flow.criteria.VlanIdCriterion;
import org.onosproject.net.flow.criteria.VlanPcpCriterion;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onosproject.net.flow.instructions.Instruction;
import org.onosproject.net.flow.instructions.Instructions;
import org.onosproject.net.flow.instructions.L0ModificationInstruction;
import org.onosproject.net.flow.instructions.L2ModificationInstruction;
import org.onosproject.net.flow.instructions.L3ModificationInstruction;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onosproject.net.flow.instructions.L4ModificationInstruction;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
......@@ -199,6 +200,9 @@ public class FlowRuleCodecTest {
} else if (instruction.type() == Instruction.Type.L3MODIFICATION) {
subType = ((L3ModificationInstruction) instruction)
.subtype().name();
} else if (instruction.type() == Instruction.Type.L4MODIFICATION) {
subType = ((L4ModificationInstruction) instruction)
.subtype().name();
} else {
subType = "";
}
......@@ -206,7 +210,7 @@ public class FlowRuleCodecTest {
instruction.type().name() + "/" + subType, instruction);
});
assertThat(rule.treatment().allInstructions().size(), is(20));
assertThat(rule.treatment().allInstructions().size(), is(24));
Instruction instruction;
......@@ -327,6 +331,30 @@ public class FlowRuleCodecTest {
assertThat(och.lambda().slotGranularity(), is(8));
assertThat(och.lambda().gridType(), is(GridType.DWDM));
assertThat(och.lambda().channelSpacing(), is(ChannelSpacing.CHL_100GHZ));
instruction = getInstruction(Instruction.Type.L4MODIFICATION,
L4ModificationInstruction.L4SubType.TCP_DST.name());
assertThat(instruction.type(), is(Instruction.Type.L4MODIFICATION));
assertThat(((L4ModificationInstruction.ModTransportPortInstruction) instruction)
.port().toInt(), is(40001));
instruction = getInstruction(Instruction.Type.L4MODIFICATION,
L4ModificationInstruction.L4SubType.TCP_SRC.name());
assertThat(instruction.type(), is(Instruction.Type.L4MODIFICATION));
assertThat(((L4ModificationInstruction.ModTransportPortInstruction) instruction)
.port().toInt(), is(40002));
instruction = getInstruction(Instruction.Type.L4MODIFICATION,
L4ModificationInstruction.L4SubType.UDP_DST.name());
assertThat(instruction.type(), is(Instruction.Type.L4MODIFICATION));
assertThat(((L4ModificationInstruction.ModTransportPortInstruction) instruction)
.port().toInt(), is(40003));
instruction = getInstruction(Instruction.Type.L4MODIFICATION,
L4ModificationInstruction.L4SubType.UDP_SRC.name());
assertThat(instruction.type(), is(Instruction.Type.L4MODIFICATION));
assertThat(((L4ModificationInstruction.ModTransportPortInstruction) instruction)
.port().toInt(), is(40004));
}
SortedMap<String, Criterion> criteria = new TreeMap<>();
......
......@@ -27,7 +27,11 @@
{"type":"L3MODIFICATION","subtype":"IPV6_FLABEL", "flowLabel":8},
{"type":"L0MODIFICATION","subtype":"LAMBDA","lambda":7},
{"type":"L0MODIFICATION","subtype":"OCH","gridType":"DWDM",
"channelSpacing":"CHL_100GHZ","spacingMultiplier":4,"slotGranularity":8}
"channelSpacing":"CHL_100GHZ","spacingMultiplier":4,"slotGranularity":8},
{"type":"L4MODIFICATION","subtype":"TCP_DST","tcpPort":40001},
{"type":"L4MODIFICATION","subtype":"TCP_SRC","tcpPort":40002},
{"type":"L4MODIFICATION","subtype":"UDP_DST","udpPort":40003},
{"type":"L4MODIFICATION","subtype":"UDP_SRC","udpPort":40004}
],
"deferred":[]
},
......