blob: 20d6fac76079485a5001bc572a140e850f6fcfe4 [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;
Jian Li47b26232016-03-07 09:59:59 -080040import org.onosproject.net.meter.MeterId;
Ray Milkeyd43fe452015-05-29 09:35:12 -070041
Jian Li1ef82db2016-03-03 14:43:21 -080042import static org.onlab.util.Tools.nullIsIllegal;
Ray Milkeyd43fe452015-05-29 09:35:12 -070043
44/**
45 * Decoding portion of the instruction codec.
46 */
Ray Milkey6d7968e2015-07-06 14:30:02 -070047public final class DecodeInstructionCodecHelper {
Ray Milkeyd43fe452015-05-29 09:35:12 -070048 private final ObjectNode json;
49
50 /**
51 * Creates a decode instruction codec object.
52 *
53 * @param json JSON object to decode
54 */
Ray Milkey6d7968e2015-07-06 14:30:02 -070055 public DecodeInstructionCodecHelper(ObjectNode json) {
Ray Milkeyd43fe452015-05-29 09:35:12 -070056 this.json = json;
57 }
58
59 /**
60 * Decodes a Layer 2 instruction.
61 *
62 * @return instruction object decoded from the JSON
63 * @throws IllegalArgumentException if the JSON is invalid
64 */
65 private Instruction decodeL2() {
66 String subType = json.get(InstructionCodec.SUBTYPE).asText();
67
68 if (subType.equals(L2ModificationInstruction.L2SubType.ETH_SRC.name())) {
69 String mac = nullIsIllegal(json.get(InstructionCodec.MAC),
70 InstructionCodec.MAC + InstructionCodec.MISSING_MEMBER_MESSAGE).asText();
71 return Instructions.modL2Src(MacAddress.valueOf(mac));
72 } else if (subType.equals(L2ModificationInstruction.L2SubType.ETH_DST.name())) {
73 String mac = nullIsIllegal(json.get(InstructionCodec.MAC),
74 InstructionCodec.MAC + InstructionCodec.MISSING_MEMBER_MESSAGE).asText();
75 return Instructions.modL2Dst(MacAddress.valueOf(mac));
76 } else if (subType.equals(L2ModificationInstruction.L2SubType.VLAN_ID.name())) {
77 short vlanId = (short) nullIsIllegal(json.get(InstructionCodec.VLAN_ID),
78 InstructionCodec.VLAN_ID + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
79 return Instructions.modVlanId(VlanId.vlanId(vlanId));
80 } else if (subType.equals(L2ModificationInstruction.L2SubType.VLAN_PCP.name())) {
81 byte vlanPcp = (byte) nullIsIllegal(json.get(InstructionCodec.VLAN_PCP),
82 InstructionCodec.VLAN_PCP + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
83 return Instructions.modVlanPcp(vlanPcp);
84 } else if (subType.equals(L2ModificationInstruction.L2SubType.MPLS_LABEL.name())) {
85 int label = nullIsIllegal(json.get(InstructionCodec.MPLS_LABEL),
86 InstructionCodec.MPLS_LABEL + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
87 return Instructions.modMplsLabel(MplsLabel.mplsLabel(label));
88 } else if (subType.equals(L2ModificationInstruction.L2SubType.MPLS_PUSH.name())) {
89 return Instructions.pushMpls();
90 } else if (subType.equals(L2ModificationInstruction.L2SubType.MPLS_POP.name())) {
91 return Instructions.popMpls();
92 } else if (subType.equals(L2ModificationInstruction.L2SubType.DEC_MPLS_TTL.name())) {
93 return Instructions.decMplsTtl();
94 } else if (subType.equals(L2ModificationInstruction.L2SubType.VLAN_POP.name())) {
95 return Instructions.popVlan();
96 } else if (subType.equals(L2ModificationInstruction.L2SubType.VLAN_PUSH.name())) {
97 return Instructions.pushVlan();
Hyunsun Moon7080a0d2015-08-14 19:18:48 -070098 } else if (subType.equals(L2ModificationInstruction.L2SubType.TUNNEL_ID.name())) {
99 long tunnelId = nullIsIllegal(json.get(InstructionCodec.TUNNEL_ID),
100 InstructionCodec.TUNNEL_ID + InstructionCodec.MISSING_MEMBER_MESSAGE).asLong();
101 return Instructions.modTunnelId(tunnelId);
Ray Milkeyd43fe452015-05-29 09:35:12 -0700102 }
103 throw new IllegalArgumentException("L2 Instruction subtype "
104 + subType + " is not supported");
105 }
106
107 /**
108 * Decodes a Layer 3 instruction.
109 *
110 * @return instruction object decoded from the JSON
111 * @throws IllegalArgumentException if the JSON is invalid
112 */
113 private Instruction decodeL3() {
114 String subType = json.get(InstructionCodec.SUBTYPE).asText();
115
116 if (subType.equals(L3ModificationInstruction.L3SubType.IPV4_SRC.name())) {
117 IpAddress ip = IpAddress.valueOf(nullIsIllegal(json.get(InstructionCodec.IP),
118 InstructionCodec.IP + InstructionCodec.MISSING_MEMBER_MESSAGE).asText());
119 return Instructions.modL3Src(ip);
120 } else if (subType.equals(L3ModificationInstruction.L3SubType.IPV4_DST.name())) {
121 IpAddress ip = IpAddress.valueOf(nullIsIllegal(json.get(InstructionCodec.IP),
122 InstructionCodec.IP + InstructionCodec.MISSING_MEMBER_MESSAGE).asText());
123 return Instructions.modL3Dst(ip);
124 } else if (subType.equals(L3ModificationInstruction.L3SubType.IPV6_SRC.name())) {
125 IpAddress ip = IpAddress.valueOf(nullIsIllegal(json.get(InstructionCodec.IP),
126 InstructionCodec.IP + InstructionCodec.MISSING_MEMBER_MESSAGE).asText());
127 return Instructions.modL3IPv6Src(ip);
128 } else if (subType.equals(L3ModificationInstruction.L3SubType.IPV6_DST.name())) {
129 IpAddress ip = IpAddress.valueOf(nullIsIllegal(json.get(InstructionCodec.IP),
130 InstructionCodec.IP + InstructionCodec.MISSING_MEMBER_MESSAGE).asText());
131 return Instructions.modL3IPv6Dst(ip);
132 } else if (subType.equals(L3ModificationInstruction.L3SubType.IPV6_FLABEL.name())) {
133 int flowLabel = nullIsIllegal(json.get(InstructionCodec.FLOW_LABEL),
134 InstructionCodec.FLOW_LABEL + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
135 return Instructions.modL3IPv6FlowLabel(flowLabel);
136 }
137 throw new IllegalArgumentException("L3 Instruction subtype "
138 + subType + " is not supported");
139 }
140
141 /**
142 * Decodes a Layer 0 instruction.
143 *
144 * @return instruction object decoded from the JSON
145 * @throws IllegalArgumentException if the JSON is invalid
146 */
147 private Instruction decodeL0() {
148 String subType = json.get(InstructionCodec.SUBTYPE).asText();
149
150
151 if (subType.equals(L0ModificationInstruction.L0SubType.LAMBDA.name())) {
152 int lambda = nullIsIllegal(json.get(InstructionCodec.LAMBDA),
153 InstructionCodec.LAMBDA + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
154 return Instructions.modL0Lambda(Lambda.indexedLambda(lambda));
155 } else if (subType.equals(L0ModificationInstruction.L0SubType.OCH.name())) {
156 String gridTypeString = nullIsIllegal(json.get(InstructionCodec.GRID_TYPE),
157 InstructionCodec.GRID_TYPE + InstructionCodec.MISSING_MEMBER_MESSAGE).asText();
158 GridType gridType = GridType.valueOf(gridTypeString);
159 if (gridType == null) {
160 throw new IllegalArgumentException("Unknown grid type "
161 + gridTypeString);
162 }
163 String channelSpacingString = nullIsIllegal(json.get(InstructionCodec.CHANNEL_SPACING),
164 InstructionCodec.CHANNEL_SPACING + InstructionCodec.MISSING_MEMBER_MESSAGE).asText();
165 ChannelSpacing channelSpacing = ChannelSpacing.valueOf(channelSpacingString);
166 if (channelSpacing == null) {
167 throw new IllegalArgumentException("Unknown channel spacing "
168 + channelSpacingString);
169 }
170 int spacingMultiplier = nullIsIllegal(json.get(InstructionCodec.SPACING_MULTIPLIER),
171 InstructionCodec.SPACING_MULTIPLIER + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
172 int slotGranularity = nullIsIllegal(json.get(InstructionCodec.SLOT_GRANULARITY),
173 InstructionCodec.SLOT_GRANULARITY + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
174 return Instructions.modL0Lambda(new OchSignal(gridType, channelSpacing,
175 spacingMultiplier, slotGranularity));
176 }
177 throw new IllegalArgumentException("L0 Instruction subtype "
178 + subType + " is not supported");
179 }
180
181 /**
Yafit Hadar5796d972015-10-15 13:16:11 +0300182 * Decodes a Layer 1 instruction.
183 *
184 * @return instruction object decoded from the JSON
185 * @throws IllegalArgumentException if the JSON is invalid
186 */
187 private Instruction decodeL1() {
188 String subType = json.get(InstructionCodec.SUBTYPE).asText();
189 if (subType.equals(L1ModificationInstruction.L1SubType.ODU_SIGID.name())) {
190 int tributaryPortNumber = nullIsIllegal(json.get(InstructionCodec.TRIBUTARY_PORT_NUMBER),
191 InstructionCodec.TRIBUTARY_PORT_NUMBER + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
192 int tributarySlotLen = nullIsIllegal(json.get(InstructionCodec.TRIBUTARY_SLOT_LEN),
193 InstructionCodec.TRIBUTARY_SLOT_LEN + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
194 byte[] tributarySlotBitmap = null;
195 tributarySlotBitmap = HexString.fromHexString(
196 nullIsIllegal(json.get(InstructionCodec.TRIBUTARY_SLOT_BITMAP),
197 InstructionCodec.TRIBUTARY_SLOT_BITMAP + InstructionCodec.MISSING_MEMBER_MESSAGE).asText());
198 return Instructions.modL1OduSignalId(OduSignalId.oduSignalId(tributaryPortNumber, tributarySlotLen,
199 tributarySlotBitmap));
200 }
201 throw new IllegalArgumentException("L1 Instruction subtype "
202 + subType + " is not supported");
203 }
204
205 /**
Hyunsun Moonfab29502015-08-25 13:39:16 -0700206 * Decodes a Layer 4 instruction.
207 *
208 * @return instruction object decoded from the JSON
209 * @throws IllegalArgumentException if the JSON is invalid
210 */
211 private Instruction decodeL4() {
212 String subType = json.get(InstructionCodec.SUBTYPE).asText();
213
214 if (subType.equals(L4ModificationInstruction.L4SubType.TCP_DST.name())) {
215 TpPort tcpPort = TpPort.tpPort(nullIsIllegal(json.get(InstructionCodec.TCP_PORT),
216 InstructionCodec.TCP_PORT + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt());
217 return Instructions.modTcpDst(tcpPort);
218 } else if (subType.equals(L4ModificationInstruction.L4SubType.TCP_SRC.name())) {
219 TpPort tcpPort = TpPort.tpPort(nullIsIllegal(json.get(InstructionCodec.TCP_PORT),
220 InstructionCodec.TCP_PORT + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt());
221 return Instructions.modTcpSrc(tcpPort);
222 } else if (subType.equals(L4ModificationInstruction.L4SubType.UDP_DST.name())) {
223 TpPort udpPort = TpPort.tpPort(nullIsIllegal(json.get(InstructionCodec.UDP_PORT),
224 InstructionCodec.UDP_PORT + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt());
225 return Instructions.modUdpDst(udpPort);
226 } else if (subType.equals(L4ModificationInstruction.L4SubType.UDP_SRC.name())) {
227 TpPort udpPort = TpPort.tpPort(nullIsIllegal(json.get(InstructionCodec.UDP_PORT),
228 InstructionCodec.UDP_PORT + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt());
229 return Instructions.modUdpSrc(udpPort);
230 }
231 throw new IllegalArgumentException("L4 Instruction subtype "
232 + subType + " is not supported");
233 }
234
235 /**
Ray Milkeyd43fe452015-05-29 09:35:12 -0700236 * Decodes the JSON into an instruction object.
237 *
238 * @return Criterion object
239 * @throws IllegalArgumentException if the JSON is invalid
240 */
241 public Instruction decode() {
242 String type = json.get(InstructionCodec.TYPE).asText();
243
244 if (type.equals(Instruction.Type.OUTPUT.name())) {
Andrea Campanella5df35952015-12-08 15:46:49 -0800245 PortNumber portNumber;
246 if (json.get(InstructionCodec.PORT).isLong() || json.get(InstructionCodec.PORT).isInt()) {
247 portNumber = PortNumber
248 .portNumber(nullIsIllegal(json.get(InstructionCodec.PORT)
249 .asLong(), InstructionCodec.PORT
250 + InstructionCodec.MISSING_MEMBER_MESSAGE));
251 } else if (json.get(InstructionCodec.PORT).isTextual()) {
252 portNumber = PortNumber
253 .fromString(nullIsIllegal(json.get(InstructionCodec.PORT)
254 .textValue(), InstructionCodec.PORT
255 + InstructionCodec.MISSING_MEMBER_MESSAGE));
256 } else {
257 throw new IllegalArgumentException("Port value "
258 + json.get(InstructionCodec.PORT).toString()
259 + " is not supported");
260 }
Ray Milkeyd43fe452015-05-29 09:35:12 -0700261 return Instructions.createOutput(portNumber);
Ray Milkey2be39ed2016-02-22 15:54:19 -0800262 } else if (type.equals(Instruction.Type.NOACTION.name())) {
263 return Instructions.createNoAction();
Jian Li1ef82db2016-03-03 14:43:21 -0800264 } else if (type.equals(Instruction.Type.TABLE.name())) {
265 return Instructions.transition(nullIsIllegal(json.get(InstructionCodec.TABLE_ID)
266 .asInt(), InstructionCodec.TABLE_ID + InstructionCodec.MISSING_MEMBER_MESSAGE));
Jian Lice8c5602016-03-03 21:43:24 -0800267 } else if (type.equals(Instruction.Type.GROUP.name())) {
268 GroupId groupId = new DefaultGroupId(nullIsIllegal(json.get(InstructionCodec.GROUP_ID)
269 .asInt(), InstructionCodec.GROUP_ID + InstructionCodec.MISSING_MEMBER_MESSAGE));
270 return Instructions.createGroup(groupId);
Jian Li47b26232016-03-07 09:59:59 -0800271 } else if (type.equals(Instruction.Type.METER.name())) {
272 MeterId meterId = MeterId.meterId(nullIsIllegal(json.get(InstructionCodec.METER_ID)
273 .asLong(), InstructionCodec.METER_ID + InstructionCodec.MISSING_MEMBER_MESSAGE));
274 return Instructions.meterTraffic(meterId);
Ray Milkeyd43fe452015-05-29 09:35:12 -0700275 } else if (type.equals(Instruction.Type.L0MODIFICATION.name())) {
276 return decodeL0();
Yafit Hadar5796d972015-10-15 13:16:11 +0300277 } else if (type.equals(Instruction.Type.L1MODIFICATION.name())) {
278 return decodeL1();
Ray Milkeyd43fe452015-05-29 09:35:12 -0700279 } else if (type.equals(Instruction.Type.L2MODIFICATION.name())) {
280 return decodeL2();
281 } else if (type.equals(Instruction.Type.L3MODIFICATION.name())) {
282 return decodeL3();
Hyunsun Moonfab29502015-08-25 13:39:16 -0700283 } else if (type.equals(Instruction.Type.L4MODIFICATION.name())) {
284 return decodeL4();
Ray Milkeyd43fe452015-05-29 09:35:12 -0700285 }
286 throw new IllegalArgumentException("Instruction type "
287 + type + " is not supported");
288 }
Ray Milkeyd43fe452015-05-29 09:35:12 -0700289}