Committed by
Gerrit Code Review
ONOS-2578 Added codec for mod tcp/udp port instructions
Change-Id: Iab1eac26afe47e0b1c13ce94e152826b0828e455
Showing
5 changed files
with
110 additions
and
7 deletions
... | @@ -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 | }, | ... | ... |
-
Please register or login to post a comment