blob: 57e73edaf4b04e921e310c22b07d0abf80beb000 [file] [log] [blame]
Ray Milkeyd43fe452015-05-29 09:35:12 -07001/*
2 * Copyright 2015 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.codec.impl;
17
Jian Li1ef82db2016-03-03 14:43:21 -080018import com.fasterxml.jackson.databind.node.ObjectNode;
Ray Milkeyd43fe452015-05-29 09:35:12 -070019import org.onlab.packet.IpAddress;
20import org.onlab.packet.MacAddress;
21import org.onlab.packet.MplsLabel;
Hyunsun Moonfab29502015-08-25 13:39:16 -070022import org.onlab.packet.TpPort;
Ray Milkeyd43fe452015-05-29 09:35:12 -070023import org.onlab.packet.VlanId;
Yafit Hadar5796d972015-10-15 13:16:11 +030024import org.onlab.util.HexString;
Jian Lice8c5602016-03-03 21:43:24 -080025import org.onosproject.core.DefaultGroupId;
26import org.onosproject.core.GroupId;
Ray Milkeyd43fe452015-05-29 09:35:12 -070027import org.onosproject.net.ChannelSpacing;
28import org.onosproject.net.GridType;
29import org.onosproject.net.Lambda;
30import org.onosproject.net.OchSignal;
Yafit Hadar5796d972015-10-15 13:16:11 +030031import org.onosproject.net.OduSignalId;
Ray Milkeyd43fe452015-05-29 09:35:12 -070032import org.onosproject.net.PortNumber;
33import org.onosproject.net.flow.instructions.Instruction;
34import org.onosproject.net.flow.instructions.Instructions;
35import org.onosproject.net.flow.instructions.L0ModificationInstruction;
Yafit Hadar5796d972015-10-15 13:16:11 +030036import org.onosproject.net.flow.instructions.L1ModificationInstruction;
Ray Milkeyd43fe452015-05-29 09:35:12 -070037import org.onosproject.net.flow.instructions.L2ModificationInstruction;
38import org.onosproject.net.flow.instructions.L3ModificationInstruction;
Hyunsun Moonfab29502015-08-25 13:39:16 -070039import org.onosproject.net.flow.instructions.L4ModificationInstruction;
Ray Milkeyd43fe452015-05-29 09:35:12 -070040
Jian Li1ef82db2016-03-03 14:43:21 -080041import static org.onlab.util.Tools.nullIsIllegal;
Ray Milkeyd43fe452015-05-29 09:35:12 -070042
43/**
44 * Decoding portion of the instruction codec.
45 */
Ray Milkey6d7968e2015-07-06 14:30:02 -070046public final class DecodeInstructionCodecHelper {
Ray Milkeyd43fe452015-05-29 09:35:12 -070047 private final ObjectNode json;
48
49 /**
50 * Creates a decode instruction codec object.
51 *
52 * @param json JSON object to decode
53 */
Ray Milkey6d7968e2015-07-06 14:30:02 -070054 public DecodeInstructionCodecHelper(ObjectNode json) {
Ray Milkeyd43fe452015-05-29 09:35:12 -070055 this.json = json;
56 }
57
58 /**
59 * Decodes a Layer 2 instruction.
60 *
61 * @return instruction object decoded from the JSON
62 * @throws IllegalArgumentException if the JSON is invalid
63 */
64 private Instruction decodeL2() {
65 String subType = json.get(InstructionCodec.SUBTYPE).asText();
66
67 if (subType.equals(L2ModificationInstruction.L2SubType.ETH_SRC.name())) {
68 String mac = nullIsIllegal(json.get(InstructionCodec.MAC),
69 InstructionCodec.MAC + InstructionCodec.MISSING_MEMBER_MESSAGE).asText();
70 return Instructions.modL2Src(MacAddress.valueOf(mac));
71 } else if (subType.equals(L2ModificationInstruction.L2SubType.ETH_DST.name())) {
72 String mac = nullIsIllegal(json.get(InstructionCodec.MAC),
73 InstructionCodec.MAC + InstructionCodec.MISSING_MEMBER_MESSAGE).asText();
74 return Instructions.modL2Dst(MacAddress.valueOf(mac));
75 } else if (subType.equals(L2ModificationInstruction.L2SubType.VLAN_ID.name())) {
76 short vlanId = (short) nullIsIllegal(json.get(InstructionCodec.VLAN_ID),
77 InstructionCodec.VLAN_ID + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
78 return Instructions.modVlanId(VlanId.vlanId(vlanId));
79 } else if (subType.equals(L2ModificationInstruction.L2SubType.VLAN_PCP.name())) {
80 byte vlanPcp = (byte) nullIsIllegal(json.get(InstructionCodec.VLAN_PCP),
81 InstructionCodec.VLAN_PCP + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
82 return Instructions.modVlanPcp(vlanPcp);
83 } else if (subType.equals(L2ModificationInstruction.L2SubType.MPLS_LABEL.name())) {
84 int label = nullIsIllegal(json.get(InstructionCodec.MPLS_LABEL),
85 InstructionCodec.MPLS_LABEL + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
86 return Instructions.modMplsLabel(MplsLabel.mplsLabel(label));
87 } else if (subType.equals(L2ModificationInstruction.L2SubType.MPLS_PUSH.name())) {
88 return Instructions.pushMpls();
89 } else if (subType.equals(L2ModificationInstruction.L2SubType.MPLS_POP.name())) {
90 return Instructions.popMpls();
91 } else if (subType.equals(L2ModificationInstruction.L2SubType.DEC_MPLS_TTL.name())) {
92 return Instructions.decMplsTtl();
93 } else if (subType.equals(L2ModificationInstruction.L2SubType.VLAN_POP.name())) {
94 return Instructions.popVlan();
95 } else if (subType.equals(L2ModificationInstruction.L2SubType.VLAN_PUSH.name())) {
96 return Instructions.pushVlan();
Hyunsun Moon7080a0d2015-08-14 19:18:48 -070097 } else if (subType.equals(L2ModificationInstruction.L2SubType.TUNNEL_ID.name())) {
98 long tunnelId = nullIsIllegal(json.get(InstructionCodec.TUNNEL_ID),
99 InstructionCodec.TUNNEL_ID + InstructionCodec.MISSING_MEMBER_MESSAGE).asLong();
100 return Instructions.modTunnelId(tunnelId);
Ray Milkeyd43fe452015-05-29 09:35:12 -0700101 }
102 throw new IllegalArgumentException("L2 Instruction subtype "
103 + subType + " is not supported");
104 }
105
106 /**
107 * Decodes a Layer 3 instruction.
108 *
109 * @return instruction object decoded from the JSON
110 * @throws IllegalArgumentException if the JSON is invalid
111 */
112 private Instruction decodeL3() {
113 String subType = json.get(InstructionCodec.SUBTYPE).asText();
114
115 if (subType.equals(L3ModificationInstruction.L3SubType.IPV4_SRC.name())) {
116 IpAddress ip = IpAddress.valueOf(nullIsIllegal(json.get(InstructionCodec.IP),
117 InstructionCodec.IP + InstructionCodec.MISSING_MEMBER_MESSAGE).asText());
118 return Instructions.modL3Src(ip);
119 } else if (subType.equals(L3ModificationInstruction.L3SubType.IPV4_DST.name())) {
120 IpAddress ip = IpAddress.valueOf(nullIsIllegal(json.get(InstructionCodec.IP),
121 InstructionCodec.IP + InstructionCodec.MISSING_MEMBER_MESSAGE).asText());
122 return Instructions.modL3Dst(ip);
123 } else if (subType.equals(L3ModificationInstruction.L3SubType.IPV6_SRC.name())) {
124 IpAddress ip = IpAddress.valueOf(nullIsIllegal(json.get(InstructionCodec.IP),
125 InstructionCodec.IP + InstructionCodec.MISSING_MEMBER_MESSAGE).asText());
126 return Instructions.modL3IPv6Src(ip);
127 } else if (subType.equals(L3ModificationInstruction.L3SubType.IPV6_DST.name())) {
128 IpAddress ip = IpAddress.valueOf(nullIsIllegal(json.get(InstructionCodec.IP),
129 InstructionCodec.IP + InstructionCodec.MISSING_MEMBER_MESSAGE).asText());
130 return Instructions.modL3IPv6Dst(ip);
131 } else if (subType.equals(L3ModificationInstruction.L3SubType.IPV6_FLABEL.name())) {
132 int flowLabel = nullIsIllegal(json.get(InstructionCodec.FLOW_LABEL),
133 InstructionCodec.FLOW_LABEL + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
134 return Instructions.modL3IPv6FlowLabel(flowLabel);
135 }
136 throw new IllegalArgumentException("L3 Instruction subtype "
137 + subType + " is not supported");
138 }
139
140 /**
141 * Decodes a Layer 0 instruction.
142 *
143 * @return instruction object decoded from the JSON
144 * @throws IllegalArgumentException if the JSON is invalid
145 */
146 private Instruction decodeL0() {
147 String subType = json.get(InstructionCodec.SUBTYPE).asText();
148
149
150 if (subType.equals(L0ModificationInstruction.L0SubType.LAMBDA.name())) {
151 int lambda = nullIsIllegal(json.get(InstructionCodec.LAMBDA),
152 InstructionCodec.LAMBDA + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
153 return Instructions.modL0Lambda(Lambda.indexedLambda(lambda));
154 } else if (subType.equals(L0ModificationInstruction.L0SubType.OCH.name())) {
155 String gridTypeString = nullIsIllegal(json.get(InstructionCodec.GRID_TYPE),
156 InstructionCodec.GRID_TYPE + InstructionCodec.MISSING_MEMBER_MESSAGE).asText();
157 GridType gridType = GridType.valueOf(gridTypeString);
158 if (gridType == null) {
159 throw new IllegalArgumentException("Unknown grid type "
160 + gridTypeString);
161 }
162 String channelSpacingString = nullIsIllegal(json.get(InstructionCodec.CHANNEL_SPACING),
163 InstructionCodec.CHANNEL_SPACING + InstructionCodec.MISSING_MEMBER_MESSAGE).asText();
164 ChannelSpacing channelSpacing = ChannelSpacing.valueOf(channelSpacingString);
165 if (channelSpacing == null) {
166 throw new IllegalArgumentException("Unknown channel spacing "
167 + channelSpacingString);
168 }
169 int spacingMultiplier = nullIsIllegal(json.get(InstructionCodec.SPACING_MULTIPLIER),
170 InstructionCodec.SPACING_MULTIPLIER + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
171 int slotGranularity = nullIsIllegal(json.get(InstructionCodec.SLOT_GRANULARITY),
172 InstructionCodec.SLOT_GRANULARITY + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
173 return Instructions.modL0Lambda(new OchSignal(gridType, channelSpacing,
174 spacingMultiplier, slotGranularity));
175 }
176 throw new IllegalArgumentException("L0 Instruction subtype "
177 + subType + " is not supported");
178 }
179
180 /**
Yafit Hadar5796d972015-10-15 13:16:11 +0300181 * Decodes a Layer 1 instruction.
182 *
183 * @return instruction object decoded from the JSON
184 * @throws IllegalArgumentException if the JSON is invalid
185 */
186 private Instruction decodeL1() {
187 String subType = json.get(InstructionCodec.SUBTYPE).asText();
188 if (subType.equals(L1ModificationInstruction.L1SubType.ODU_SIGID.name())) {
189 int tributaryPortNumber = nullIsIllegal(json.get(InstructionCodec.TRIBUTARY_PORT_NUMBER),
190 InstructionCodec.TRIBUTARY_PORT_NUMBER + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
191 int tributarySlotLen = nullIsIllegal(json.get(InstructionCodec.TRIBUTARY_SLOT_LEN),
192 InstructionCodec.TRIBUTARY_SLOT_LEN + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
193 byte[] tributarySlotBitmap = null;
194 tributarySlotBitmap = HexString.fromHexString(
195 nullIsIllegal(json.get(InstructionCodec.TRIBUTARY_SLOT_BITMAP),
196 InstructionCodec.TRIBUTARY_SLOT_BITMAP + InstructionCodec.MISSING_MEMBER_MESSAGE).asText());
197 return Instructions.modL1OduSignalId(OduSignalId.oduSignalId(tributaryPortNumber, tributarySlotLen,
198 tributarySlotBitmap));
199 }
200 throw new IllegalArgumentException("L1 Instruction subtype "
201 + subType + " is not supported");
202 }
203
204 /**
Hyunsun Moonfab29502015-08-25 13:39:16 -0700205 * Decodes a Layer 4 instruction.
206 *
207 * @return instruction object decoded from the JSON
208 * @throws IllegalArgumentException if the JSON is invalid
209 */
210 private Instruction decodeL4() {
211 String subType = json.get(InstructionCodec.SUBTYPE).asText();
212
213 if (subType.equals(L4ModificationInstruction.L4SubType.TCP_DST.name())) {
214 TpPort tcpPort = TpPort.tpPort(nullIsIllegal(json.get(InstructionCodec.TCP_PORT),
215 InstructionCodec.TCP_PORT + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt());
216 return Instructions.modTcpDst(tcpPort);
217 } else if (subType.equals(L4ModificationInstruction.L4SubType.TCP_SRC.name())) {
218 TpPort tcpPort = TpPort.tpPort(nullIsIllegal(json.get(InstructionCodec.TCP_PORT),
219 InstructionCodec.TCP_PORT + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt());
220 return Instructions.modTcpSrc(tcpPort);
221 } else if (subType.equals(L4ModificationInstruction.L4SubType.UDP_DST.name())) {
222 TpPort udpPort = TpPort.tpPort(nullIsIllegal(json.get(InstructionCodec.UDP_PORT),
223 InstructionCodec.UDP_PORT + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt());
224 return Instructions.modUdpDst(udpPort);
225 } else if (subType.equals(L4ModificationInstruction.L4SubType.UDP_SRC.name())) {
226 TpPort udpPort = TpPort.tpPort(nullIsIllegal(json.get(InstructionCodec.UDP_PORT),
227 InstructionCodec.UDP_PORT + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt());
228 return Instructions.modUdpSrc(udpPort);
229 }
230 throw new IllegalArgumentException("L4 Instruction subtype "
231 + subType + " is not supported");
232 }
233
234 /**
Ray Milkeyd43fe452015-05-29 09:35:12 -0700235 * Decodes the JSON into an instruction object.
236 *
237 * @return Criterion object
238 * @throws IllegalArgumentException if the JSON is invalid
239 */
240 public Instruction decode() {
241 String type = json.get(InstructionCodec.TYPE).asText();
242
243 if (type.equals(Instruction.Type.OUTPUT.name())) {
Andrea Campanella5df35952015-12-08 15:46:49 -0800244 PortNumber portNumber;
245 if (json.get(InstructionCodec.PORT).isLong() || json.get(InstructionCodec.PORT).isInt()) {
246 portNumber = PortNumber
247 .portNumber(nullIsIllegal(json.get(InstructionCodec.PORT)
248 .asLong(), InstructionCodec.PORT
249 + InstructionCodec.MISSING_MEMBER_MESSAGE));
250 } else if (json.get(InstructionCodec.PORT).isTextual()) {
251 portNumber = PortNumber
252 .fromString(nullIsIllegal(json.get(InstructionCodec.PORT)
253 .textValue(), InstructionCodec.PORT
254 + InstructionCodec.MISSING_MEMBER_MESSAGE));
255 } else {
256 throw new IllegalArgumentException("Port value "
257 + json.get(InstructionCodec.PORT).toString()
258 + " is not supported");
259 }
Ray Milkeyd43fe452015-05-29 09:35:12 -0700260 return Instructions.createOutput(portNumber);
Ray Milkey2be39ed2016-02-22 15:54:19 -0800261 } else if (type.equals(Instruction.Type.NOACTION.name())) {
262 return Instructions.createNoAction();
Jian Li1ef82db2016-03-03 14:43:21 -0800263 } else if (type.equals(Instruction.Type.TABLE.name())) {
264 return Instructions.transition(nullIsIllegal(json.get(InstructionCodec.TABLE_ID)
265 .asInt(), InstructionCodec.TABLE_ID + InstructionCodec.MISSING_MEMBER_MESSAGE));
Jian Lice8c5602016-03-03 21:43:24 -0800266 } else if (type.equals(Instruction.Type.GROUP.name())) {
267 GroupId groupId = new DefaultGroupId(nullIsIllegal(json.get(InstructionCodec.GROUP_ID)
268 .asInt(), InstructionCodec.GROUP_ID + InstructionCodec.MISSING_MEMBER_MESSAGE));
269 return Instructions.createGroup(groupId);
Ray Milkeyd43fe452015-05-29 09:35:12 -0700270 } else if (type.equals(Instruction.Type.L0MODIFICATION.name())) {
271 return decodeL0();
Yafit Hadar5796d972015-10-15 13:16:11 +0300272 } else if (type.equals(Instruction.Type.L1MODIFICATION.name())) {
273 return decodeL1();
Ray Milkeyd43fe452015-05-29 09:35:12 -0700274 } else if (type.equals(Instruction.Type.L2MODIFICATION.name())) {
275 return decodeL2();
276 } else if (type.equals(Instruction.Type.L3MODIFICATION.name())) {
277 return decodeL3();
Hyunsun Moonfab29502015-08-25 13:39:16 -0700278 } else if (type.equals(Instruction.Type.L4MODIFICATION.name())) {
279 return decodeL4();
Ray Milkeyd43fe452015-05-29 09:35:12 -0700280 }
281 throw new IllegalArgumentException("Instruction type "
282 + type + " is not supported");
283 }
Ray Milkeyd43fe452015-05-29 09:35:12 -0700284}