blob: 105924ef970ada35cd6fc316ff6de17028dfcbc2 [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;
Ray Milkeyd43fe452015-05-29 09:35:12 -070025import org.onosproject.net.ChannelSpacing;
26import org.onosproject.net.GridType;
27import org.onosproject.net.Lambda;
28import org.onosproject.net.OchSignal;
Yafit Hadar5796d972015-10-15 13:16:11 +030029import org.onosproject.net.OduSignalId;
Ray Milkeyd43fe452015-05-29 09:35:12 -070030import org.onosproject.net.PortNumber;
31import org.onosproject.net.flow.instructions.Instruction;
32import org.onosproject.net.flow.instructions.Instructions;
33import org.onosproject.net.flow.instructions.L0ModificationInstruction;
Yafit Hadar5796d972015-10-15 13:16:11 +030034import org.onosproject.net.flow.instructions.L1ModificationInstruction;
Ray Milkeyd43fe452015-05-29 09:35:12 -070035import org.onosproject.net.flow.instructions.L2ModificationInstruction;
36import org.onosproject.net.flow.instructions.L3ModificationInstruction;
Hyunsun Moonfab29502015-08-25 13:39:16 -070037import org.onosproject.net.flow.instructions.L4ModificationInstruction;
Ray Milkeyd43fe452015-05-29 09:35:12 -070038
Jian Li1ef82db2016-03-03 14:43:21 -080039import static org.onlab.util.Tools.nullIsIllegal;
Ray Milkeyd43fe452015-05-29 09:35:12 -070040
41/**
42 * Decoding portion of the instruction codec.
43 */
Ray Milkey6d7968e2015-07-06 14:30:02 -070044public final class DecodeInstructionCodecHelper {
Ray Milkeyd43fe452015-05-29 09:35:12 -070045 private final ObjectNode json;
46
47 /**
48 * Creates a decode instruction codec object.
49 *
50 * @param json JSON object to decode
51 */
Ray Milkey6d7968e2015-07-06 14:30:02 -070052 public DecodeInstructionCodecHelper(ObjectNode json) {
Ray Milkeyd43fe452015-05-29 09:35:12 -070053 this.json = json;
54 }
55
56 /**
57 * Decodes a Layer 2 instruction.
58 *
59 * @return instruction object decoded from the JSON
60 * @throws IllegalArgumentException if the JSON is invalid
61 */
62 private Instruction decodeL2() {
63 String subType = json.get(InstructionCodec.SUBTYPE).asText();
64
65 if (subType.equals(L2ModificationInstruction.L2SubType.ETH_SRC.name())) {
66 String mac = nullIsIllegal(json.get(InstructionCodec.MAC),
67 InstructionCodec.MAC + InstructionCodec.MISSING_MEMBER_MESSAGE).asText();
68 return Instructions.modL2Src(MacAddress.valueOf(mac));
69 } else if (subType.equals(L2ModificationInstruction.L2SubType.ETH_DST.name())) {
70 String mac = nullIsIllegal(json.get(InstructionCodec.MAC),
71 InstructionCodec.MAC + InstructionCodec.MISSING_MEMBER_MESSAGE).asText();
72 return Instructions.modL2Dst(MacAddress.valueOf(mac));
73 } else if (subType.equals(L2ModificationInstruction.L2SubType.VLAN_ID.name())) {
74 short vlanId = (short) nullIsIllegal(json.get(InstructionCodec.VLAN_ID),
75 InstructionCodec.VLAN_ID + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
76 return Instructions.modVlanId(VlanId.vlanId(vlanId));
77 } else if (subType.equals(L2ModificationInstruction.L2SubType.VLAN_PCP.name())) {
78 byte vlanPcp = (byte) nullIsIllegal(json.get(InstructionCodec.VLAN_PCP),
79 InstructionCodec.VLAN_PCP + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
80 return Instructions.modVlanPcp(vlanPcp);
81 } else if (subType.equals(L2ModificationInstruction.L2SubType.MPLS_LABEL.name())) {
82 int label = nullIsIllegal(json.get(InstructionCodec.MPLS_LABEL),
83 InstructionCodec.MPLS_LABEL + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
84 return Instructions.modMplsLabel(MplsLabel.mplsLabel(label));
85 } else if (subType.equals(L2ModificationInstruction.L2SubType.MPLS_PUSH.name())) {
86 return Instructions.pushMpls();
87 } else if (subType.equals(L2ModificationInstruction.L2SubType.MPLS_POP.name())) {
88 return Instructions.popMpls();
89 } else if (subType.equals(L2ModificationInstruction.L2SubType.DEC_MPLS_TTL.name())) {
90 return Instructions.decMplsTtl();
91 } else if (subType.equals(L2ModificationInstruction.L2SubType.VLAN_POP.name())) {
92 return Instructions.popVlan();
93 } else if (subType.equals(L2ModificationInstruction.L2SubType.VLAN_PUSH.name())) {
94 return Instructions.pushVlan();
Hyunsun Moon7080a0d2015-08-14 19:18:48 -070095 } else if (subType.equals(L2ModificationInstruction.L2SubType.TUNNEL_ID.name())) {
96 long tunnelId = nullIsIllegal(json.get(InstructionCodec.TUNNEL_ID),
97 InstructionCodec.TUNNEL_ID + InstructionCodec.MISSING_MEMBER_MESSAGE).asLong();
98 return Instructions.modTunnelId(tunnelId);
Ray Milkeyd43fe452015-05-29 09:35:12 -070099 }
100 throw new IllegalArgumentException("L2 Instruction subtype "
101 + subType + " is not supported");
102 }
103
104 /**
105 * Decodes a Layer 3 instruction.
106 *
107 * @return instruction object decoded from the JSON
108 * @throws IllegalArgumentException if the JSON is invalid
109 */
110 private Instruction decodeL3() {
111 String subType = json.get(InstructionCodec.SUBTYPE).asText();
112
113 if (subType.equals(L3ModificationInstruction.L3SubType.IPV4_SRC.name())) {
114 IpAddress ip = IpAddress.valueOf(nullIsIllegal(json.get(InstructionCodec.IP),
115 InstructionCodec.IP + InstructionCodec.MISSING_MEMBER_MESSAGE).asText());
116 return Instructions.modL3Src(ip);
117 } else if (subType.equals(L3ModificationInstruction.L3SubType.IPV4_DST.name())) {
118 IpAddress ip = IpAddress.valueOf(nullIsIllegal(json.get(InstructionCodec.IP),
119 InstructionCodec.IP + InstructionCodec.MISSING_MEMBER_MESSAGE).asText());
120 return Instructions.modL3Dst(ip);
121 } else if (subType.equals(L3ModificationInstruction.L3SubType.IPV6_SRC.name())) {
122 IpAddress ip = IpAddress.valueOf(nullIsIllegal(json.get(InstructionCodec.IP),
123 InstructionCodec.IP + InstructionCodec.MISSING_MEMBER_MESSAGE).asText());
124 return Instructions.modL3IPv6Src(ip);
125 } else if (subType.equals(L3ModificationInstruction.L3SubType.IPV6_DST.name())) {
126 IpAddress ip = IpAddress.valueOf(nullIsIllegal(json.get(InstructionCodec.IP),
127 InstructionCodec.IP + InstructionCodec.MISSING_MEMBER_MESSAGE).asText());
128 return Instructions.modL3IPv6Dst(ip);
129 } else if (subType.equals(L3ModificationInstruction.L3SubType.IPV6_FLABEL.name())) {
130 int flowLabel = nullIsIllegal(json.get(InstructionCodec.FLOW_LABEL),
131 InstructionCodec.FLOW_LABEL + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
132 return Instructions.modL3IPv6FlowLabel(flowLabel);
133 }
134 throw new IllegalArgumentException("L3 Instruction subtype "
135 + subType + " is not supported");
136 }
137
138 /**
139 * Decodes a Layer 0 instruction.
140 *
141 * @return instruction object decoded from the JSON
142 * @throws IllegalArgumentException if the JSON is invalid
143 */
144 private Instruction decodeL0() {
145 String subType = json.get(InstructionCodec.SUBTYPE).asText();
146
147
148 if (subType.equals(L0ModificationInstruction.L0SubType.LAMBDA.name())) {
149 int lambda = nullIsIllegal(json.get(InstructionCodec.LAMBDA),
150 InstructionCodec.LAMBDA + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
151 return Instructions.modL0Lambda(Lambda.indexedLambda(lambda));
152 } else if (subType.equals(L0ModificationInstruction.L0SubType.OCH.name())) {
153 String gridTypeString = nullIsIllegal(json.get(InstructionCodec.GRID_TYPE),
154 InstructionCodec.GRID_TYPE + InstructionCodec.MISSING_MEMBER_MESSAGE).asText();
155 GridType gridType = GridType.valueOf(gridTypeString);
156 if (gridType == null) {
157 throw new IllegalArgumentException("Unknown grid type "
158 + gridTypeString);
159 }
160 String channelSpacingString = nullIsIllegal(json.get(InstructionCodec.CHANNEL_SPACING),
161 InstructionCodec.CHANNEL_SPACING + InstructionCodec.MISSING_MEMBER_MESSAGE).asText();
162 ChannelSpacing channelSpacing = ChannelSpacing.valueOf(channelSpacingString);
163 if (channelSpacing == null) {
164 throw new IllegalArgumentException("Unknown channel spacing "
165 + channelSpacingString);
166 }
167 int spacingMultiplier = nullIsIllegal(json.get(InstructionCodec.SPACING_MULTIPLIER),
168 InstructionCodec.SPACING_MULTIPLIER + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
169 int slotGranularity = nullIsIllegal(json.get(InstructionCodec.SLOT_GRANULARITY),
170 InstructionCodec.SLOT_GRANULARITY + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
171 return Instructions.modL0Lambda(new OchSignal(gridType, channelSpacing,
172 spacingMultiplier, slotGranularity));
173 }
174 throw new IllegalArgumentException("L0 Instruction subtype "
175 + subType + " is not supported");
176 }
177
178 /**
Yafit Hadar5796d972015-10-15 13:16:11 +0300179 * Decodes a Layer 1 instruction.
180 *
181 * @return instruction object decoded from the JSON
182 * @throws IllegalArgumentException if the JSON is invalid
183 */
184 private Instruction decodeL1() {
185 String subType = json.get(InstructionCodec.SUBTYPE).asText();
186 if (subType.equals(L1ModificationInstruction.L1SubType.ODU_SIGID.name())) {
187 int tributaryPortNumber = nullIsIllegal(json.get(InstructionCodec.TRIBUTARY_PORT_NUMBER),
188 InstructionCodec.TRIBUTARY_PORT_NUMBER + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
189 int tributarySlotLen = nullIsIllegal(json.get(InstructionCodec.TRIBUTARY_SLOT_LEN),
190 InstructionCodec.TRIBUTARY_SLOT_LEN + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
191 byte[] tributarySlotBitmap = null;
192 tributarySlotBitmap = HexString.fromHexString(
193 nullIsIllegal(json.get(InstructionCodec.TRIBUTARY_SLOT_BITMAP),
194 InstructionCodec.TRIBUTARY_SLOT_BITMAP + InstructionCodec.MISSING_MEMBER_MESSAGE).asText());
195 return Instructions.modL1OduSignalId(OduSignalId.oduSignalId(tributaryPortNumber, tributarySlotLen,
196 tributarySlotBitmap));
197 }
198 throw new IllegalArgumentException("L1 Instruction subtype "
199 + subType + " is not supported");
200 }
201
202 /**
Hyunsun Moonfab29502015-08-25 13:39:16 -0700203 * Decodes a Layer 4 instruction.
204 *
205 * @return instruction object decoded from the JSON
206 * @throws IllegalArgumentException if the JSON is invalid
207 */
208 private Instruction decodeL4() {
209 String subType = json.get(InstructionCodec.SUBTYPE).asText();
210
211 if (subType.equals(L4ModificationInstruction.L4SubType.TCP_DST.name())) {
212 TpPort tcpPort = TpPort.tpPort(nullIsIllegal(json.get(InstructionCodec.TCP_PORT),
213 InstructionCodec.TCP_PORT + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt());
214 return Instructions.modTcpDst(tcpPort);
215 } else if (subType.equals(L4ModificationInstruction.L4SubType.TCP_SRC.name())) {
216 TpPort tcpPort = TpPort.tpPort(nullIsIllegal(json.get(InstructionCodec.TCP_PORT),
217 InstructionCodec.TCP_PORT + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt());
218 return Instructions.modTcpSrc(tcpPort);
219 } else if (subType.equals(L4ModificationInstruction.L4SubType.UDP_DST.name())) {
220 TpPort udpPort = TpPort.tpPort(nullIsIllegal(json.get(InstructionCodec.UDP_PORT),
221 InstructionCodec.UDP_PORT + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt());
222 return Instructions.modUdpDst(udpPort);
223 } else if (subType.equals(L4ModificationInstruction.L4SubType.UDP_SRC.name())) {
224 TpPort udpPort = TpPort.tpPort(nullIsIllegal(json.get(InstructionCodec.UDP_PORT),
225 InstructionCodec.UDP_PORT + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt());
226 return Instructions.modUdpSrc(udpPort);
227 }
228 throw new IllegalArgumentException("L4 Instruction subtype "
229 + subType + " is not supported");
230 }
231
232 /**
Ray Milkeyd43fe452015-05-29 09:35:12 -0700233 * Decodes the JSON into an instruction object.
234 *
235 * @return Criterion object
236 * @throws IllegalArgumentException if the JSON is invalid
237 */
238 public Instruction decode() {
239 String type = json.get(InstructionCodec.TYPE).asText();
240
241 if (type.equals(Instruction.Type.OUTPUT.name())) {
Andrea Campanella5df35952015-12-08 15:46:49 -0800242 PortNumber portNumber;
243 if (json.get(InstructionCodec.PORT).isLong() || json.get(InstructionCodec.PORT).isInt()) {
244 portNumber = PortNumber
245 .portNumber(nullIsIllegal(json.get(InstructionCodec.PORT)
246 .asLong(), InstructionCodec.PORT
247 + InstructionCodec.MISSING_MEMBER_MESSAGE));
248 } else if (json.get(InstructionCodec.PORT).isTextual()) {
249 portNumber = PortNumber
250 .fromString(nullIsIllegal(json.get(InstructionCodec.PORT)
251 .textValue(), InstructionCodec.PORT
252 + InstructionCodec.MISSING_MEMBER_MESSAGE));
253 } else {
254 throw new IllegalArgumentException("Port value "
255 + json.get(InstructionCodec.PORT).toString()
256 + " is not supported");
257 }
Ray Milkeyd43fe452015-05-29 09:35:12 -0700258 return Instructions.createOutput(portNumber);
Ray Milkey2be39ed2016-02-22 15:54:19 -0800259 } else if (type.equals(Instruction.Type.NOACTION.name())) {
260 return Instructions.createNoAction();
Jian Li1ef82db2016-03-03 14:43:21 -0800261 } else if (type.equals(Instruction.Type.TABLE.name())) {
262 return Instructions.transition(nullIsIllegal(json.get(InstructionCodec.TABLE_ID)
263 .asInt(), InstructionCodec.TABLE_ID + InstructionCodec.MISSING_MEMBER_MESSAGE));
Ray Milkeyd43fe452015-05-29 09:35:12 -0700264 } else if (type.equals(Instruction.Type.L0MODIFICATION.name())) {
265 return decodeL0();
Yafit Hadar5796d972015-10-15 13:16:11 +0300266 } else if (type.equals(Instruction.Type.L1MODIFICATION.name())) {
267 return decodeL1();
Ray Milkeyd43fe452015-05-29 09:35:12 -0700268 } else if (type.equals(Instruction.Type.L2MODIFICATION.name())) {
269 return decodeL2();
270 } else if (type.equals(Instruction.Type.L3MODIFICATION.name())) {
271 return decodeL3();
Hyunsun Moonfab29502015-08-25 13:39:16 -0700272 } else if (type.equals(Instruction.Type.L4MODIFICATION.name())) {
273 return decodeL4();
Ray Milkeyd43fe452015-05-29 09:35:12 -0700274 }
275 throw new IllegalArgumentException("Instruction type "
276 + type + " is not supported");
277 }
Ray Milkeyd43fe452015-05-29 09:35:12 -0700278}