2 * Copyright 2015 Open Networking Laboratory
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package org.onosproject.codec.impl;
18 import org.onlab.packet.IpAddress;
19 import org.onlab.packet.MacAddress;
20 import org.onlab.packet.MplsLabel;
21 import org.onlab.packet.TpPort;
22 import org.onlab.packet.VlanId;
23 import org.onosproject.net.ChannelSpacing;
24 import org.onosproject.net.GridType;
25 import org.onosproject.net.Lambda;
26 import org.onosproject.net.OchSignal;
27 import org.onosproject.net.PortNumber;
29 import com.fasterxml.jackson.databind.node.ObjectNode;
30 import org.onosproject.net.flow.instructions.Instruction;
31 import org.onosproject.net.flow.instructions.Instructions;
32 import org.onosproject.net.flow.instructions.L0ModificationInstruction;
33 import org.onosproject.net.flow.instructions.L2ModificationInstruction;
34 import org.onosproject.net.flow.instructions.L3ModificationInstruction;
35 import org.onosproject.net.flow.instructions.L4ModificationInstruction;
37 import static org.onlab.util.Tools.nullIsIllegal;
40 * Decoding portion of the instruction codec.
42 public final class DecodeInstructionCodecHelper {
43 private final ObjectNode json;
46 * Creates a decode instruction codec object.
48 * @param json JSON object to decode
50 public DecodeInstructionCodecHelper(ObjectNode json) {
55 * Decodes a Layer 2 instruction.
57 * @return instruction object decoded from the JSON
58 * @throws IllegalArgumentException if the JSON is invalid
60 private Instruction decodeL2() {
61 String subType = json.get(InstructionCodec.SUBTYPE).asText();
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();
93 } 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);
98 throw new IllegalArgumentException("L2 Instruction subtype "
99 + subType + " is not supported");
103 * Decodes a Layer 3 instruction.
105 * @return instruction object decoded from the JSON
106 * @throws IllegalArgumentException if the JSON is invalid
108 private Instruction decodeL3() {
109 String subType = json.get(InstructionCodec.SUBTYPE).asText();
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);
132 throw new IllegalArgumentException("L3 Instruction subtype "
133 + subType + " is not supported");
137 * Decodes a Layer 0 instruction.
139 * @return instruction object decoded from the JSON
140 * @throws IllegalArgumentException if the JSON is invalid
142 private Instruction decodeL0() {
143 String subType = json.get(InstructionCodec.SUBTYPE).asText();
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 "
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);
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));
172 throw new IllegalArgumentException("L0 Instruction subtype "
173 + subType + " is not supported");
177 * Decodes a Layer 4 instruction.
179 * @return instruction object decoded from the JSON
180 * @throws IllegalArgumentException if the JSON is invalid
182 private Instruction decodeL4() {
183 String subType = json.get(InstructionCodec.SUBTYPE).asText();
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);
202 throw new IllegalArgumentException("L4 Instruction subtype "
203 + subType + " is not supported");
207 * Decodes the JSON into an instruction object.
209 * @return Criterion object
210 * @throws IllegalArgumentException if the JSON is invalid
212 public Instruction decode() {
213 String type = json.get(InstructionCodec.TYPE).asText();
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())) {
224 } else if (type.equals(Instruction.Type.L2MODIFICATION.name())) {
226 } else if (type.equals(Instruction.Type.L3MODIFICATION.name())) {
228 } else if (type.equals(Instruction.Type.L4MODIFICATION.name())) {
231 throw new IllegalArgumentException("Instruction type "
232 + type + " is not supported");