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; ...@@ -18,19 +18,21 @@ package org.onosproject.codec.impl;
18 import org.onlab.packet.IpAddress; 18 import org.onlab.packet.IpAddress;
19 import org.onlab.packet.MacAddress; 19 import org.onlab.packet.MacAddress;
20 import org.onlab.packet.MplsLabel; 20 import org.onlab.packet.MplsLabel;
21 +import org.onlab.packet.TpPort;
21 import org.onlab.packet.VlanId; 22 import org.onlab.packet.VlanId;
22 import org.onosproject.net.ChannelSpacing; 23 import org.onosproject.net.ChannelSpacing;
23 import org.onosproject.net.GridType; 24 import org.onosproject.net.GridType;
24 import org.onosproject.net.Lambda; 25 import org.onosproject.net.Lambda;
25 import org.onosproject.net.OchSignal; 26 import org.onosproject.net.OchSignal;
26 import org.onosproject.net.PortNumber; 27 import org.onosproject.net.PortNumber;
28 +
29 +import com.fasterxml.jackson.databind.node.ObjectNode;
27 import org.onosproject.net.flow.instructions.Instruction; 30 import org.onosproject.net.flow.instructions.Instruction;
28 import org.onosproject.net.flow.instructions.Instructions; 31 import org.onosproject.net.flow.instructions.Instructions;
29 import org.onosproject.net.flow.instructions.L0ModificationInstruction; 32 import org.onosproject.net.flow.instructions.L0ModificationInstruction;
30 import org.onosproject.net.flow.instructions.L2ModificationInstruction; 33 import org.onosproject.net.flow.instructions.L2ModificationInstruction;
31 import org.onosproject.net.flow.instructions.L3ModificationInstruction; 34 import org.onosproject.net.flow.instructions.L3ModificationInstruction;
32 - 35 +import org.onosproject.net.flow.instructions.L4ModificationInstruction;
33 -import com.fasterxml.jackson.databind.node.ObjectNode;
34 36
35 import static org.onlab.util.Tools.nullIsIllegal; 37 import static org.onlab.util.Tools.nullIsIllegal;
36 38
...@@ -172,6 +174,36 @@ public final class DecodeInstructionCodecHelper { ...@@ -172,6 +174,36 @@ public final class DecodeInstructionCodecHelper {
172 } 174 }
173 175
174 /** 176 /**
177 + * Decodes a Layer 4 instruction.
178 + *
179 + * @return instruction object decoded from the JSON
180 + * @throws IllegalArgumentException if the JSON is invalid
181 + */
182 + private Instruction decodeL4() {
183 + String subType = json.get(InstructionCodec.SUBTYPE).asText();
184 +
185 + if (subType.equals(L4ModificationInstruction.L4SubType.TCP_DST.name())) {
186 + TpPort tcpPort = TpPort.tpPort(nullIsIllegal(json.get(InstructionCodec.TCP_PORT),
187 + InstructionCodec.TCP_PORT + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt());
188 + return Instructions.modTcpDst(tcpPort);
189 + } else if (subType.equals(L4ModificationInstruction.L4SubType.TCP_SRC.name())) {
190 + TpPort tcpPort = TpPort.tpPort(nullIsIllegal(json.get(InstructionCodec.TCP_PORT),
191 + InstructionCodec.TCP_PORT + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt());
192 + return Instructions.modTcpSrc(tcpPort);
193 + } else if (subType.equals(L4ModificationInstruction.L4SubType.UDP_DST.name())) {
194 + TpPort udpPort = TpPort.tpPort(nullIsIllegal(json.get(InstructionCodec.UDP_PORT),
195 + InstructionCodec.UDP_PORT + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt());
196 + return Instructions.modUdpDst(udpPort);
197 + } else if (subType.equals(L4ModificationInstruction.L4SubType.UDP_SRC.name())) {
198 + TpPort udpPort = TpPort.tpPort(nullIsIllegal(json.get(InstructionCodec.UDP_PORT),
199 + InstructionCodec.UDP_PORT + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt());
200 + return Instructions.modUdpSrc(udpPort);
201 + }
202 + throw new IllegalArgumentException("L4 Instruction subtype "
203 + + subType + " is not supported");
204 + }
205 +
206 + /**
175 * Decodes the JSON into an instruction object. 207 * Decodes the JSON into an instruction object.
176 * 208 *
177 * @return Criterion object 209 * @return Criterion object
...@@ -193,6 +225,8 @@ public final class DecodeInstructionCodecHelper { ...@@ -193,6 +225,8 @@ public final class DecodeInstructionCodecHelper {
193 return decodeL2(); 225 return decodeL2();
194 } else if (type.equals(Instruction.Type.L3MODIFICATION.name())) { 226 } else if (type.equals(Instruction.Type.L3MODIFICATION.name())) {
195 return decodeL3(); 227 return decodeL3();
228 + } else if (type.equals(Instruction.Type.L4MODIFICATION.name())) {
229 + return decodeL4();
196 } 230 }
197 throw new IllegalArgumentException("Instruction type " 231 throw new IllegalArgumentException("Instruction type "
198 + type + " is not supported"); 232 + type + " is not supported");
......
...@@ -22,6 +22,7 @@ import org.onosproject.net.flow.instructions.Instructions; ...@@ -22,6 +22,7 @@ import org.onosproject.net.flow.instructions.Instructions;
22 import org.onosproject.net.flow.instructions.L0ModificationInstruction; 22 import org.onosproject.net.flow.instructions.L0ModificationInstruction;
23 import org.onosproject.net.flow.instructions.L2ModificationInstruction; 23 import org.onosproject.net.flow.instructions.L2ModificationInstruction;
24 import org.onosproject.net.flow.instructions.L3ModificationInstruction; 24 import org.onosproject.net.flow.instructions.L3ModificationInstruction;
25 +import org.onosproject.net.flow.instructions.L4ModificationInstruction;
25 import org.slf4j.Logger; 26 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory; 27 import org.slf4j.LoggerFactory;
27 28
...@@ -168,6 +169,36 @@ public final class EncodeInstructionCodecHelper { ...@@ -168,6 +169,36 @@ public final class EncodeInstructionCodecHelper {
168 } 169 }
169 170
170 /** 171 /**
172 + * Encode a L4 modification instruction.
173 + *
174 + * @param result json node that the instruction attributes are added to
175 + */
176 + private void encodeL4(ObjectNode result) {
177 + L4ModificationInstruction instruction =
178 + (L4ModificationInstruction) this.instruction;
179 + result.put(InstructionCodec.SUBTYPE, instruction.subtype().name());
180 + switch (instruction.subtype()) {
181 + case TCP_DST:
182 + case TCP_SRC:
183 + final L4ModificationInstruction.ModTransportPortInstruction modTcpPortInstruction =
184 + (L4ModificationInstruction.ModTransportPortInstruction) instruction;
185 + result.put(InstructionCodec.TCP_PORT, modTcpPortInstruction.port().toInt());
186 + break;
187 +
188 + case UDP_DST:
189 + case UDP_SRC:
190 + final L4ModificationInstruction.ModTransportPortInstruction modUdpPortInstruction =
191 + (L4ModificationInstruction.ModTransportPortInstruction) instruction;
192 + result.put(InstructionCodec.UDP_PORT, modUdpPortInstruction.port().toInt());
193 + break;
194 +
195 + default:
196 + log.info("Cannot convert L4 subtype of {}", instruction.subtype());
197 + break;
198 + }
199 + }
200 +
201 + /**
171 * Encodes the given instruction into JSON. 202 * Encodes the given instruction into JSON.
172 * 203 *
173 * @return JSON object node representing the instruction 204 * @return JSON object node representing the instruction
...@@ -198,6 +229,10 @@ public final class EncodeInstructionCodecHelper { ...@@ -198,6 +229,10 @@ public final class EncodeInstructionCodecHelper {
198 encodeL3(result); 229 encodeL3(result);
199 break; 230 break;
200 231
232 + case L4MODIFICATION:
233 + encodeL4(result);
234 + break;
235 +
201 default: 236 default:
202 log.info("Cannot convert instruction type of {}", instruction.type()); 237 log.info("Cannot convert instruction type of {}", instruction.type());
203 break; 238 break;
......
...@@ -48,6 +48,8 @@ public final class InstructionCodec extends JsonCodec<Instruction> { ...@@ -48,6 +48,8 @@ public final class InstructionCodec extends JsonCodec<Instruction> {
48 protected static final String SLOT_GRANULARITY = "slotGranularity"; 48 protected static final String SLOT_GRANULARITY = "slotGranularity";
49 protected static final String ETHERNET_TYPE = "ethernetType"; 49 protected static final String ETHERNET_TYPE = "ethernetType";
50 protected static final String TUNNEL_ID = "tunnelId"; 50 protected static final String TUNNEL_ID = "tunnelId";
51 + protected static final String TCP_PORT = "tcpPort";
52 + protected static final String UDP_PORT = "udpPort";
51 53
52 protected static final String MISSING_MEMBER_MESSAGE = 54 protected static final String MISSING_MEMBER_MESSAGE =
53 " member is required in Instruction"; 55 " member is required in Instruction";
......
...@@ -62,14 +62,15 @@ import org.onosproject.net.flow.criteria.TunnelIdCriterion; ...@@ -62,14 +62,15 @@ import org.onosproject.net.flow.criteria.TunnelIdCriterion;
62 import org.onosproject.net.flow.criteria.UdpPortCriterion; 62 import org.onosproject.net.flow.criteria.UdpPortCriterion;
63 import org.onosproject.net.flow.criteria.VlanIdCriterion; 63 import org.onosproject.net.flow.criteria.VlanIdCriterion;
64 import org.onosproject.net.flow.criteria.VlanPcpCriterion; 64 import org.onosproject.net.flow.criteria.VlanPcpCriterion;
65 +
66 +import com.fasterxml.jackson.databind.JsonNode;
67 +import com.fasterxml.jackson.databind.node.ObjectNode;
65 import org.onosproject.net.flow.instructions.Instruction; 68 import org.onosproject.net.flow.instructions.Instruction;
66 import org.onosproject.net.flow.instructions.Instructions; 69 import org.onosproject.net.flow.instructions.Instructions;
67 import org.onosproject.net.flow.instructions.L0ModificationInstruction; 70 import org.onosproject.net.flow.instructions.L0ModificationInstruction;
68 import org.onosproject.net.flow.instructions.L2ModificationInstruction; 71 import org.onosproject.net.flow.instructions.L2ModificationInstruction;
69 import org.onosproject.net.flow.instructions.L3ModificationInstruction; 72 import org.onosproject.net.flow.instructions.L3ModificationInstruction;
70 - 73 +import org.onosproject.net.flow.instructions.L4ModificationInstruction;
71 -import com.fasterxml.jackson.databind.JsonNode;
72 -import com.fasterxml.jackson.databind.node.ObjectNode;
73 74
74 import static org.easymock.EasyMock.createMock; 75 import static org.easymock.EasyMock.createMock;
75 import static org.easymock.EasyMock.expect; 76 import static org.easymock.EasyMock.expect;
...@@ -199,6 +200,9 @@ public class FlowRuleCodecTest { ...@@ -199,6 +200,9 @@ public class FlowRuleCodecTest {
199 } else if (instruction.type() == Instruction.Type.L3MODIFICATION) { 200 } else if (instruction.type() == Instruction.Type.L3MODIFICATION) {
200 subType = ((L3ModificationInstruction) instruction) 201 subType = ((L3ModificationInstruction) instruction)
201 .subtype().name(); 202 .subtype().name();
203 + } else if (instruction.type() == Instruction.Type.L4MODIFICATION) {
204 + subType = ((L4ModificationInstruction) instruction)
205 + .subtype().name();
202 } else { 206 } else {
203 subType = ""; 207 subType = "";
204 } 208 }
...@@ -206,7 +210,7 @@ public class FlowRuleCodecTest { ...@@ -206,7 +210,7 @@ public class FlowRuleCodecTest {
206 instruction.type().name() + "/" + subType, instruction); 210 instruction.type().name() + "/" + subType, instruction);
207 }); 211 });
208 212
209 - assertThat(rule.treatment().allInstructions().size(), is(20)); 213 + assertThat(rule.treatment().allInstructions().size(), is(24));
210 214
211 Instruction instruction; 215 Instruction instruction;
212 216
...@@ -327,6 +331,30 @@ public class FlowRuleCodecTest { ...@@ -327,6 +331,30 @@ public class FlowRuleCodecTest {
327 assertThat(och.lambda().slotGranularity(), is(8)); 331 assertThat(och.lambda().slotGranularity(), is(8));
328 assertThat(och.lambda().gridType(), is(GridType.DWDM)); 332 assertThat(och.lambda().gridType(), is(GridType.DWDM));
329 assertThat(och.lambda().channelSpacing(), is(ChannelSpacing.CHL_100GHZ)); 333 assertThat(och.lambda().channelSpacing(), is(ChannelSpacing.CHL_100GHZ));
334 +
335 + instruction = getInstruction(Instruction.Type.L4MODIFICATION,
336 + L4ModificationInstruction.L4SubType.TCP_DST.name());
337 + assertThat(instruction.type(), is(Instruction.Type.L4MODIFICATION));
338 + assertThat(((L4ModificationInstruction.ModTransportPortInstruction) instruction)
339 + .port().toInt(), is(40001));
340 +
341 + instruction = getInstruction(Instruction.Type.L4MODIFICATION,
342 + L4ModificationInstruction.L4SubType.TCP_SRC.name());
343 + assertThat(instruction.type(), is(Instruction.Type.L4MODIFICATION));
344 + assertThat(((L4ModificationInstruction.ModTransportPortInstruction) instruction)
345 + .port().toInt(), is(40002));
346 +
347 + instruction = getInstruction(Instruction.Type.L4MODIFICATION,
348 + L4ModificationInstruction.L4SubType.UDP_DST.name());
349 + assertThat(instruction.type(), is(Instruction.Type.L4MODIFICATION));
350 + assertThat(((L4ModificationInstruction.ModTransportPortInstruction) instruction)
351 + .port().toInt(), is(40003));
352 +
353 + instruction = getInstruction(Instruction.Type.L4MODIFICATION,
354 + L4ModificationInstruction.L4SubType.UDP_SRC.name());
355 + assertThat(instruction.type(), is(Instruction.Type.L4MODIFICATION));
356 + assertThat(((L4ModificationInstruction.ModTransportPortInstruction) instruction)
357 + .port().toInt(), is(40004));
330 } 358 }
331 359
332 SortedMap<String, Criterion> criteria = new TreeMap<>(); 360 SortedMap<String, Criterion> criteria = new TreeMap<>();
......
...@@ -27,7 +27,11 @@ ...@@ -27,7 +27,11 @@
27 {"type":"L3MODIFICATION","subtype":"IPV6_FLABEL", "flowLabel":8}, 27 {"type":"L3MODIFICATION","subtype":"IPV6_FLABEL", "flowLabel":8},
28 {"type":"L0MODIFICATION","subtype":"LAMBDA","lambda":7}, 28 {"type":"L0MODIFICATION","subtype":"LAMBDA","lambda":7},
29 {"type":"L0MODIFICATION","subtype":"OCH","gridType":"DWDM", 29 {"type":"L0MODIFICATION","subtype":"OCH","gridType":"DWDM",
30 - "channelSpacing":"CHL_100GHZ","spacingMultiplier":4,"slotGranularity":8} 30 + "channelSpacing":"CHL_100GHZ","spacingMultiplier":4,"slotGranularity":8},
31 + {"type":"L4MODIFICATION","subtype":"TCP_DST","tcpPort":40001},
32 + {"type":"L4MODIFICATION","subtype":"TCP_SRC","tcpPort":40002},
33 + {"type":"L4MODIFICATION","subtype":"UDP_DST","udpPort":40003},
34 + {"type":"L4MODIFICATION","subtype":"UDP_SRC","udpPort":40004}
31 ], 35 ],
32 "deferred":[] 36 "deferred":[]
33 }, 37 },
......