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