blob: 568fa7646b5960061b98d91faed0a66bd2b5b96f [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;
21import org.onlab.packet.VlanId;
22import org.onosproject.net.ChannelSpacing;
23import org.onosproject.net.GridType;
24import org.onosproject.net.Lambda;
25import org.onosproject.net.OchSignal;
26import org.onosproject.net.PortNumber;
27import org.onosproject.net.flow.instructions.Instruction;
28import org.onosproject.net.flow.instructions.Instructions;
29import org.onosproject.net.flow.instructions.L0ModificationInstruction;
30import org.onosproject.net.flow.instructions.L2ModificationInstruction;
31import org.onosproject.net.flow.instructions.L3ModificationInstruction;
32
33import com.fasterxml.jackson.databind.node.ObjectNode;
34
35import static org.onlab.util.Tools.nullIsIllegal;
36
37/**
38 * Decoding portion of the instruction codec.
39 */
Ray Milkey6d7968e2015-07-06 14:30:02 -070040public final class DecodeInstructionCodecHelper {
Ray Milkeyd43fe452015-05-29 09:35:12 -070041 private final ObjectNode json;
42
43 /**
44 * Creates a decode instruction codec object.
45 *
46 * @param json JSON object to decode
47 */
Ray Milkey6d7968e2015-07-06 14:30:02 -070048 public DecodeInstructionCodecHelper(ObjectNode json) {
Ray Milkeyd43fe452015-05-29 09:35:12 -070049 this.json = json;
50 }
51
52 /**
53 * Decodes a Layer 2 instruction.
54 *
55 * @return instruction object decoded from the JSON
56 * @throws IllegalArgumentException if the JSON is invalid
57 */
58 private Instruction decodeL2() {
59 String subType = json.get(InstructionCodec.SUBTYPE).asText();
60
61 if (subType.equals(L2ModificationInstruction.L2SubType.ETH_SRC.name())) {
62 String mac = nullIsIllegal(json.get(InstructionCodec.MAC),
63 InstructionCodec.MAC + InstructionCodec.MISSING_MEMBER_MESSAGE).asText();
64 return Instructions.modL2Src(MacAddress.valueOf(mac));
65 } else if (subType.equals(L2ModificationInstruction.L2SubType.ETH_DST.name())) {
66 String mac = nullIsIllegal(json.get(InstructionCodec.MAC),
67 InstructionCodec.MAC + InstructionCodec.MISSING_MEMBER_MESSAGE).asText();
68 return Instructions.modL2Dst(MacAddress.valueOf(mac));
69 } else if (subType.equals(L2ModificationInstruction.L2SubType.VLAN_ID.name())) {
70 short vlanId = (short) nullIsIllegal(json.get(InstructionCodec.VLAN_ID),
71 InstructionCodec.VLAN_ID + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
72 return Instructions.modVlanId(VlanId.vlanId(vlanId));
73 } else if (subType.equals(L2ModificationInstruction.L2SubType.VLAN_PCP.name())) {
74 byte vlanPcp = (byte) nullIsIllegal(json.get(InstructionCodec.VLAN_PCP),
75 InstructionCodec.VLAN_PCP + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
76 return Instructions.modVlanPcp(vlanPcp);
77 } else if (subType.equals(L2ModificationInstruction.L2SubType.MPLS_LABEL.name())) {
78 int label = nullIsIllegal(json.get(InstructionCodec.MPLS_LABEL),
79 InstructionCodec.MPLS_LABEL + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
80 return Instructions.modMplsLabel(MplsLabel.mplsLabel(label));
81 } else if (subType.equals(L2ModificationInstruction.L2SubType.MPLS_PUSH.name())) {
82 return Instructions.pushMpls();
83 } else if (subType.equals(L2ModificationInstruction.L2SubType.MPLS_POP.name())) {
84 return Instructions.popMpls();
85 } else if (subType.equals(L2ModificationInstruction.L2SubType.DEC_MPLS_TTL.name())) {
86 return Instructions.decMplsTtl();
87 } else if (subType.equals(L2ModificationInstruction.L2SubType.VLAN_POP.name())) {
88 return Instructions.popVlan();
89 } else if (subType.equals(L2ModificationInstruction.L2SubType.VLAN_PUSH.name())) {
90 return Instructions.pushVlan();
Hyunsun Moon7080a0d2015-08-14 19:18:48 -070091 } else if (subType.equals(L2ModificationInstruction.L2SubType.TUNNEL_ID.name())) {
92 long tunnelId = nullIsIllegal(json.get(InstructionCodec.TUNNEL_ID),
93 InstructionCodec.TUNNEL_ID + InstructionCodec.MISSING_MEMBER_MESSAGE).asLong();
94 return Instructions.modTunnelId(tunnelId);
Ray Milkeyd43fe452015-05-29 09:35:12 -070095 }
96 throw new IllegalArgumentException("L2 Instruction subtype "
97 + subType + " is not supported");
98 }
99
100 /**
101 * Decodes a Layer 3 instruction.
102 *
103 * @return instruction object decoded from the JSON
104 * @throws IllegalArgumentException if the JSON is invalid
105 */
106 private Instruction decodeL3() {
107 String subType = json.get(InstructionCodec.SUBTYPE).asText();
108
109 if (subType.equals(L3ModificationInstruction.L3SubType.IPV4_SRC.name())) {
110 IpAddress ip = IpAddress.valueOf(nullIsIllegal(json.get(InstructionCodec.IP),
111 InstructionCodec.IP + InstructionCodec.MISSING_MEMBER_MESSAGE).asText());
112 return Instructions.modL3Src(ip);
113 } else if (subType.equals(L3ModificationInstruction.L3SubType.IPV4_DST.name())) {
114 IpAddress ip = IpAddress.valueOf(nullIsIllegal(json.get(InstructionCodec.IP),
115 InstructionCodec.IP + InstructionCodec.MISSING_MEMBER_MESSAGE).asText());
116 return Instructions.modL3Dst(ip);
117 } else if (subType.equals(L3ModificationInstruction.L3SubType.IPV6_SRC.name())) {
118 IpAddress ip = IpAddress.valueOf(nullIsIllegal(json.get(InstructionCodec.IP),
119 InstructionCodec.IP + InstructionCodec.MISSING_MEMBER_MESSAGE).asText());
120 return Instructions.modL3IPv6Src(ip);
121 } else if (subType.equals(L3ModificationInstruction.L3SubType.IPV6_DST.name())) {
122 IpAddress ip = IpAddress.valueOf(nullIsIllegal(json.get(InstructionCodec.IP),
123 InstructionCodec.IP + InstructionCodec.MISSING_MEMBER_MESSAGE).asText());
124 return Instructions.modL3IPv6Dst(ip);
125 } else if (subType.equals(L3ModificationInstruction.L3SubType.IPV6_FLABEL.name())) {
126 int flowLabel = nullIsIllegal(json.get(InstructionCodec.FLOW_LABEL),
127 InstructionCodec.FLOW_LABEL + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
128 return Instructions.modL3IPv6FlowLabel(flowLabel);
129 }
130 throw new IllegalArgumentException("L3 Instruction subtype "
131 + subType + " is not supported");
132 }
133
134 /**
135 * Decodes a Layer 0 instruction.
136 *
137 * @return instruction object decoded from the JSON
138 * @throws IllegalArgumentException if the JSON is invalid
139 */
140 private Instruction decodeL0() {
141 String subType = json.get(InstructionCodec.SUBTYPE).asText();
142
143
144 if (subType.equals(L0ModificationInstruction.L0SubType.LAMBDA.name())) {
145 int lambda = nullIsIllegal(json.get(InstructionCodec.LAMBDA),
146 InstructionCodec.LAMBDA + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
147 return Instructions.modL0Lambda(Lambda.indexedLambda(lambda));
148 } else if (subType.equals(L0ModificationInstruction.L0SubType.OCH.name())) {
149 String gridTypeString = nullIsIllegal(json.get(InstructionCodec.GRID_TYPE),
150 InstructionCodec.GRID_TYPE + InstructionCodec.MISSING_MEMBER_MESSAGE).asText();
151 GridType gridType = GridType.valueOf(gridTypeString);
152 if (gridType == null) {
153 throw new IllegalArgumentException("Unknown grid type "
154 + gridTypeString);
155 }
156 String channelSpacingString = nullIsIllegal(json.get(InstructionCodec.CHANNEL_SPACING),
157 InstructionCodec.CHANNEL_SPACING + InstructionCodec.MISSING_MEMBER_MESSAGE).asText();
158 ChannelSpacing channelSpacing = ChannelSpacing.valueOf(channelSpacingString);
159 if (channelSpacing == null) {
160 throw new IllegalArgumentException("Unknown channel spacing "
161 + channelSpacingString);
162 }
163 int spacingMultiplier = nullIsIllegal(json.get(InstructionCodec.SPACING_MULTIPLIER),
164 InstructionCodec.SPACING_MULTIPLIER + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
165 int slotGranularity = nullIsIllegal(json.get(InstructionCodec.SLOT_GRANULARITY),
166 InstructionCodec.SLOT_GRANULARITY + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
167 return Instructions.modL0Lambda(new OchSignal(gridType, channelSpacing,
168 spacingMultiplier, slotGranularity));
169 }
170 throw new IllegalArgumentException("L0 Instruction subtype "
171 + subType + " is not supported");
172 }
173
174 /**
175 * Decodes the JSON into an instruction object.
176 *
177 * @return Criterion object
178 * @throws IllegalArgumentException if the JSON is invalid
179 */
180 public Instruction decode() {
181 String type = json.get(InstructionCodec.TYPE).asText();
182
183 if (type.equals(Instruction.Type.OUTPUT.name())) {
184 PortNumber portNumber =
185 PortNumber.portNumber(nullIsIllegal(json.get(InstructionCodec.PORT),
186 InstructionCodec.PORT + InstructionCodec.MISSING_MEMBER_MESSAGE).asLong());
187 return Instructions.createOutput(portNumber);
188 } else if (type.equals(Instruction.Type.DROP.name())) {
189 return Instructions.createDrop();
190 } else if (type.equals(Instruction.Type.L0MODIFICATION.name())) {
191 return decodeL0();
192 } else if (type.equals(Instruction.Type.L2MODIFICATION.name())) {
193 return decodeL2();
194 } else if (type.equals(Instruction.Type.L3MODIFICATION.name())) {
195 return decodeL3();
196 }
197 throw new IllegalArgumentException("Instruction type "
198 + type + " is not supported");
199 }
200
201}