blob: 6a97a07609b8c5b890fdff25b13c8ae6eb22ead5 [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
18import org.onlab.packet.IpAddress;
19import org.onlab.packet.MacAddress;
20import org.onlab.packet.MplsLabel;
Hyunsun Moonfab29502015-08-25 13:39:16 -070021import org.onlab.packet.TpPort;
Ray Milkeyd43fe452015-05-29 09:35:12 -070022import org.onlab.packet.VlanId;
23import org.onosproject.net.ChannelSpacing;
24import org.onosproject.net.GridType;
25import org.onosproject.net.Lambda;
26import org.onosproject.net.OchSignal;
27import org.onosproject.net.PortNumber;
Hyunsun Moonfab29502015-08-25 13:39:16 -070028
29import com.fasterxml.jackson.databind.node.ObjectNode;
Ray Milkeyd43fe452015-05-29 09:35:12 -070030import org.onosproject.net.flow.instructions.Instruction;
31import org.onosproject.net.flow.instructions.Instructions;
32import org.onosproject.net.flow.instructions.L0ModificationInstruction;
33import org.onosproject.net.flow.instructions.L2ModificationInstruction;
34import org.onosproject.net.flow.instructions.L3ModificationInstruction;
Hyunsun Moonfab29502015-08-25 13:39:16 -070035import org.onosproject.net.flow.instructions.L4ModificationInstruction;
Ray Milkeyd43fe452015-05-29 09:35:12 -070036
37import static org.onlab.util.Tools.nullIsIllegal;
38
39/**
40 * Decoding portion of the instruction codec.
41 */
Ray Milkey6d7968e2015-07-06 14:30:02 -070042public final class DecodeInstructionCodecHelper {
Ray Milkeyd43fe452015-05-29 09:35:12 -070043 private final ObjectNode json;
44
45 /**
46 * Creates a decode instruction codec object.
47 *
48 * @param json JSON object to decode
49 */
Ray Milkey6d7968e2015-07-06 14:30:02 -070050 public DecodeInstructionCodecHelper(ObjectNode json) {
Ray Milkeyd43fe452015-05-29 09:35:12 -070051 this.json = json;
52 }
53
54 /**
55 * Decodes a Layer 2 instruction.
56 *
57 * @return instruction object decoded from the JSON
58 * @throws IllegalArgumentException if the JSON is invalid
59 */
60 private Instruction decodeL2() {
61 String subType = json.get(InstructionCodec.SUBTYPE).asText();
62
63 if (subType.equals(L2ModificationInstruction.L2SubType.ETH_SRC.name())) {
64 String mac = nullIsIllegal(json.get(InstructionCodec.MAC),
65 InstructionCodec.MAC + InstructionCodec.MISSING_MEMBER_MESSAGE).asText();
66 return Instructions.modL2Src(MacAddress.valueOf(mac));
67 } else if (subType.equals(L2ModificationInstruction.L2SubType.ETH_DST.name())) {
68 String mac = nullIsIllegal(json.get(InstructionCodec.MAC),
69 InstructionCodec.MAC + InstructionCodec.MISSING_MEMBER_MESSAGE).asText();
70 return Instructions.modL2Dst(MacAddress.valueOf(mac));
71 } else if (subType.equals(L2ModificationInstruction.L2SubType.VLAN_ID.name())) {
72 short vlanId = (short) nullIsIllegal(json.get(InstructionCodec.VLAN_ID),
73 InstructionCodec.VLAN_ID + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
74 return Instructions.modVlanId(VlanId.vlanId(vlanId));
75 } else if (subType.equals(L2ModificationInstruction.L2SubType.VLAN_PCP.name())) {
76 byte vlanPcp = (byte) nullIsIllegal(json.get(InstructionCodec.VLAN_PCP),
77 InstructionCodec.VLAN_PCP + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
78 return Instructions.modVlanPcp(vlanPcp);
79 } else if (subType.equals(L2ModificationInstruction.L2SubType.MPLS_LABEL.name())) {
80 int label = nullIsIllegal(json.get(InstructionCodec.MPLS_LABEL),
81 InstructionCodec.MPLS_LABEL + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
82 return Instructions.modMplsLabel(MplsLabel.mplsLabel(label));
83 } else if (subType.equals(L2ModificationInstruction.L2SubType.MPLS_PUSH.name())) {
84 return Instructions.pushMpls();
85 } else if (subType.equals(L2ModificationInstruction.L2SubType.MPLS_POP.name())) {
86 return Instructions.popMpls();
87 } else if (subType.equals(L2ModificationInstruction.L2SubType.DEC_MPLS_TTL.name())) {
88 return Instructions.decMplsTtl();
89 } else if (subType.equals(L2ModificationInstruction.L2SubType.VLAN_POP.name())) {
90 return Instructions.popVlan();
91 } else if (subType.equals(L2ModificationInstruction.L2SubType.VLAN_PUSH.name())) {
92 return Instructions.pushVlan();
Hyunsun Moon7080a0d2015-08-14 19:18:48 -070093 } else if (subType.equals(L2ModificationInstruction.L2SubType.TUNNEL_ID.name())) {
94 long tunnelId = nullIsIllegal(json.get(InstructionCodec.TUNNEL_ID),
95 InstructionCodec.TUNNEL_ID + InstructionCodec.MISSING_MEMBER_MESSAGE).asLong();
96 return Instructions.modTunnelId(tunnelId);
Ray Milkeyd43fe452015-05-29 09:35:12 -070097 }
98 throw new IllegalArgumentException("L2 Instruction subtype "
99 + subType + " is not supported");
100 }
101
102 /**
103 * Decodes a Layer 3 instruction.
104 *
105 * @return instruction object decoded from the JSON
106 * @throws IllegalArgumentException if the JSON is invalid
107 */
108 private Instruction decodeL3() {
109 String subType = json.get(InstructionCodec.SUBTYPE).asText();
110
111 if (subType.equals(L3ModificationInstruction.L3SubType.IPV4_SRC.name())) {
112 IpAddress ip = IpAddress.valueOf(nullIsIllegal(json.get(InstructionCodec.IP),
113 InstructionCodec.IP + InstructionCodec.MISSING_MEMBER_MESSAGE).asText());
114 return Instructions.modL3Src(ip);
115 } else if (subType.equals(L3ModificationInstruction.L3SubType.IPV4_DST.name())) {
116 IpAddress ip = IpAddress.valueOf(nullIsIllegal(json.get(InstructionCodec.IP),
117 InstructionCodec.IP + InstructionCodec.MISSING_MEMBER_MESSAGE).asText());
118 return Instructions.modL3Dst(ip);
119 } else if (subType.equals(L3ModificationInstruction.L3SubType.IPV6_SRC.name())) {
120 IpAddress ip = IpAddress.valueOf(nullIsIllegal(json.get(InstructionCodec.IP),
121 InstructionCodec.IP + InstructionCodec.MISSING_MEMBER_MESSAGE).asText());
122 return Instructions.modL3IPv6Src(ip);
123 } else if (subType.equals(L3ModificationInstruction.L3SubType.IPV6_DST.name())) {
124 IpAddress ip = IpAddress.valueOf(nullIsIllegal(json.get(InstructionCodec.IP),
125 InstructionCodec.IP + InstructionCodec.MISSING_MEMBER_MESSAGE).asText());
126 return Instructions.modL3IPv6Dst(ip);
127 } else if (subType.equals(L3ModificationInstruction.L3SubType.IPV6_FLABEL.name())) {
128 int flowLabel = nullIsIllegal(json.get(InstructionCodec.FLOW_LABEL),
129 InstructionCodec.FLOW_LABEL + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
130 return Instructions.modL3IPv6FlowLabel(flowLabel);
131 }
132 throw new IllegalArgumentException("L3 Instruction subtype "
133 + subType + " is not supported");
134 }
135
136 /**
137 * Decodes a Layer 0 instruction.
138 *
139 * @return instruction object decoded from the JSON
140 * @throws IllegalArgumentException if the JSON is invalid
141 */
142 private Instruction decodeL0() {
143 String subType = json.get(InstructionCodec.SUBTYPE).asText();
144
145
146 if (subType.equals(L0ModificationInstruction.L0SubType.LAMBDA.name())) {
147 int lambda = nullIsIllegal(json.get(InstructionCodec.LAMBDA),
148 InstructionCodec.LAMBDA + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
149 return Instructions.modL0Lambda(Lambda.indexedLambda(lambda));
150 } else if (subType.equals(L0ModificationInstruction.L0SubType.OCH.name())) {
151 String gridTypeString = nullIsIllegal(json.get(InstructionCodec.GRID_TYPE),
152 InstructionCodec.GRID_TYPE + InstructionCodec.MISSING_MEMBER_MESSAGE).asText();
153 GridType gridType = GridType.valueOf(gridTypeString);
154 if (gridType == null) {
155 throw new IllegalArgumentException("Unknown grid type "
156 + gridTypeString);
157 }
158 String channelSpacingString = nullIsIllegal(json.get(InstructionCodec.CHANNEL_SPACING),
159 InstructionCodec.CHANNEL_SPACING + InstructionCodec.MISSING_MEMBER_MESSAGE).asText();
160 ChannelSpacing channelSpacing = ChannelSpacing.valueOf(channelSpacingString);
161 if (channelSpacing == null) {
162 throw new IllegalArgumentException("Unknown channel spacing "
163 + channelSpacingString);
164 }
165 int spacingMultiplier = nullIsIllegal(json.get(InstructionCodec.SPACING_MULTIPLIER),
166 InstructionCodec.SPACING_MULTIPLIER + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
167 int slotGranularity = nullIsIllegal(json.get(InstructionCodec.SLOT_GRANULARITY),
168 InstructionCodec.SLOT_GRANULARITY + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
169 return Instructions.modL0Lambda(new OchSignal(gridType, channelSpacing,
170 spacingMultiplier, slotGranularity));
171 }
172 throw new IllegalArgumentException("L0 Instruction subtype "
173 + subType + " is not supported");
174 }
175
176 /**
Hyunsun Moonfab29502015-08-25 13:39:16 -0700177 * 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 /**
Ray Milkeyd43fe452015-05-29 09:35:12 -0700207 * Decodes the JSON into an instruction object.
208 *
209 * @return Criterion object
210 * @throws IllegalArgumentException if the JSON is invalid
211 */
212 public Instruction decode() {
213 String type = json.get(InstructionCodec.TYPE).asText();
214
215 if (type.equals(Instruction.Type.OUTPUT.name())) {
216 PortNumber portNumber =
217 PortNumber.portNumber(nullIsIllegal(json.get(InstructionCodec.PORT),
218 InstructionCodec.PORT + InstructionCodec.MISSING_MEMBER_MESSAGE).asLong());
219 return Instructions.createOutput(portNumber);
220 } else if (type.equals(Instruction.Type.DROP.name())) {
221 return Instructions.createDrop();
222 } else if (type.equals(Instruction.Type.L0MODIFICATION.name())) {
223 return decodeL0();
224 } else if (type.equals(Instruction.Type.L2MODIFICATION.name())) {
225 return decodeL2();
226 } else if (type.equals(Instruction.Type.L3MODIFICATION.name())) {
227 return decodeL3();
Hyunsun Moonfab29502015-08-25 13:39:16 -0700228 } else if (type.equals(Instruction.Type.L4MODIFICATION.name())) {
229 return decodeL4();
Ray Milkeyd43fe452015-05-29 09:35:12 -0700230 }
231 throw new IllegalArgumentException("Instruction type "
232 + type + " is not supported");
233 }
234
235}