blob: 48dfbdce7d7a34f4945d11778284cee24e815a85 [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 */
40public final class DecodeInstructionCodec {
41 private final ObjectNode json;
42
43 /**
44 * Creates a decode instruction codec object.
45 *
46 * @param json JSON object to decode
47 */
48 public DecodeInstructionCodec(ObjectNode json) {
49 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();
91 }
92 throw new IllegalArgumentException("L2 Instruction subtype "
93 + subType + " is not supported");
94 }
95
96 /**
97 * Decodes a Layer 3 instruction.
98 *
99 * @return instruction object decoded from the JSON
100 * @throws IllegalArgumentException if the JSON is invalid
101 */
102 private Instruction decodeL3() {
103 String subType = json.get(InstructionCodec.SUBTYPE).asText();
104
105 if (subType.equals(L3ModificationInstruction.L3SubType.IPV4_SRC.name())) {
106 IpAddress ip = IpAddress.valueOf(nullIsIllegal(json.get(InstructionCodec.IP),
107 InstructionCodec.IP + InstructionCodec.MISSING_MEMBER_MESSAGE).asText());
108 return Instructions.modL3Src(ip);
109 } else if (subType.equals(L3ModificationInstruction.L3SubType.IPV4_DST.name())) {
110 IpAddress ip = IpAddress.valueOf(nullIsIllegal(json.get(InstructionCodec.IP),
111 InstructionCodec.IP + InstructionCodec.MISSING_MEMBER_MESSAGE).asText());
112 return Instructions.modL3Dst(ip);
113 } else if (subType.equals(L3ModificationInstruction.L3SubType.IPV6_SRC.name())) {
114 IpAddress ip = IpAddress.valueOf(nullIsIllegal(json.get(InstructionCodec.IP),
115 InstructionCodec.IP + InstructionCodec.MISSING_MEMBER_MESSAGE).asText());
116 return Instructions.modL3IPv6Src(ip);
117 } else if (subType.equals(L3ModificationInstruction.L3SubType.IPV6_DST.name())) {
118 IpAddress ip = IpAddress.valueOf(nullIsIllegal(json.get(InstructionCodec.IP),
119 InstructionCodec.IP + InstructionCodec.MISSING_MEMBER_MESSAGE).asText());
120 return Instructions.modL3IPv6Dst(ip);
121 } else if (subType.equals(L3ModificationInstruction.L3SubType.IPV6_FLABEL.name())) {
122 int flowLabel = nullIsIllegal(json.get(InstructionCodec.FLOW_LABEL),
123 InstructionCodec.FLOW_LABEL + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
124 return Instructions.modL3IPv6FlowLabel(flowLabel);
125 }
126 throw new IllegalArgumentException("L3 Instruction subtype "
127 + subType + " is not supported");
128 }
129
130 /**
131 * Decodes a Layer 0 instruction.
132 *
133 * @return instruction object decoded from the JSON
134 * @throws IllegalArgumentException if the JSON is invalid
135 */
136 private Instruction decodeL0() {
137 String subType = json.get(InstructionCodec.SUBTYPE).asText();
138
139
140 if (subType.equals(L0ModificationInstruction.L0SubType.LAMBDA.name())) {
141 int lambda = nullIsIllegal(json.get(InstructionCodec.LAMBDA),
142 InstructionCodec.LAMBDA + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
143 return Instructions.modL0Lambda(Lambda.indexedLambda(lambda));
144 } else if (subType.equals(L0ModificationInstruction.L0SubType.OCH.name())) {
145 String gridTypeString = nullIsIllegal(json.get(InstructionCodec.GRID_TYPE),
146 InstructionCodec.GRID_TYPE + InstructionCodec.MISSING_MEMBER_MESSAGE).asText();
147 GridType gridType = GridType.valueOf(gridTypeString);
148 if (gridType == null) {
149 throw new IllegalArgumentException("Unknown grid type "
150 + gridTypeString);
151 }
152 String channelSpacingString = nullIsIllegal(json.get(InstructionCodec.CHANNEL_SPACING),
153 InstructionCodec.CHANNEL_SPACING + InstructionCodec.MISSING_MEMBER_MESSAGE).asText();
154 ChannelSpacing channelSpacing = ChannelSpacing.valueOf(channelSpacingString);
155 if (channelSpacing == null) {
156 throw new IllegalArgumentException("Unknown channel spacing "
157 + channelSpacingString);
158 }
159 int spacingMultiplier = nullIsIllegal(json.get(InstructionCodec.SPACING_MULTIPLIER),
160 InstructionCodec.SPACING_MULTIPLIER + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
161 int slotGranularity = nullIsIllegal(json.get(InstructionCodec.SLOT_GRANULARITY),
162 InstructionCodec.SLOT_GRANULARITY + InstructionCodec.MISSING_MEMBER_MESSAGE).asInt();
163 return Instructions.modL0Lambda(new OchSignal(gridType, channelSpacing,
164 spacingMultiplier, slotGranularity));
165 }
166 throw new IllegalArgumentException("L0 Instruction subtype "
167 + subType + " is not supported");
168 }
169
170 /**
171 * Decodes the JSON into an instruction object.
172 *
173 * @return Criterion object
174 * @throws IllegalArgumentException if the JSON is invalid
175 */
176 public Instruction decode() {
177 String type = json.get(InstructionCodec.TYPE).asText();
178
179 if (type.equals(Instruction.Type.OUTPUT.name())) {
180 PortNumber portNumber =
181 PortNumber.portNumber(nullIsIllegal(json.get(InstructionCodec.PORT),
182 InstructionCodec.PORT + InstructionCodec.MISSING_MEMBER_MESSAGE).asLong());
183 return Instructions.createOutput(portNumber);
184 } else if (type.equals(Instruction.Type.DROP.name())) {
185 return Instructions.createDrop();
186 } else if (type.equals(Instruction.Type.L0MODIFICATION.name())) {
187 return decodeL0();
188 } else if (type.equals(Instruction.Type.L2MODIFICATION.name())) {
189 return decodeL2();
190 } else if (type.equals(Instruction.Type.L3MODIFICATION.name())) {
191 return decodeL3();
192 }
193 throw new IllegalArgumentException("Instruction type "
194 + type + " is not supported");
195 }
196
197}