blob: 27a0b405d084304ef675665650f1d1daac3ffc7c [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 java.util.HashMap;
19import java.util.Map;
20
21import org.onlab.packet.Ip6Address;
22import org.onlab.packet.IpPrefix;
23import org.onlab.packet.MacAddress;
24import org.onlab.packet.MplsLabel;
25import org.onlab.packet.VlanId;
26import org.onosproject.net.ChannelSpacing;
27import org.onosproject.net.GridType;
28import org.onosproject.net.Lambda;
29import org.onosproject.net.PortNumber;
30import org.onosproject.net.flow.criteria.Criteria;
31import org.onosproject.net.flow.criteria.Criterion;
32
33import com.fasterxml.jackson.databind.JsonNode;
34import com.fasterxml.jackson.databind.node.ObjectNode;
35
36import static org.onlab.util.Tools.nullIsIllegal;
37
38/**
39 * Decode portion of the criterion codec.
40 */
41public final class DecodeCriterionCodec {
42
43 private final ObjectNode json;
44
45 protected static final String MISSING_MEMBER_MESSAGE =
46 " member is required in Criterion";
47
48 private interface CriterionDecoder {
49 Criterion decodeCriterion(ObjectNode json);
50 }
51 private final Map<String, CriterionDecoder> decoderMap;
52
53 /**
54 * Creates a decode criterion codec object.
55 * Initializes the lookup map for criterion subclass decoders.
56 *
57 * @param json JSON object to decode
58 */
59 public DecodeCriterionCodec(ObjectNode json) {
60 this.json = json;
61 decoderMap = new HashMap<>();
62
63 decoderMap.put(Criterion.Type.IN_PORT.name(), new InPortDecoder());
64 decoderMap.put(Criterion.Type.IN_PHY_PORT.name(), new InPhyPortDecoder());
65 decoderMap.put(Criterion.Type.METADATA.name(), new MetadataDecoder());
66 decoderMap.put(Criterion.Type.ETH_DST.name(), new EthDstDecoder());
67 decoderMap.put(Criterion.Type.ETH_SRC.name(), new EthSrcDecoder());
68 decoderMap.put(Criterion.Type.ETH_TYPE.name(), new EthTypeDecoder());
69 decoderMap.put(Criterion.Type.VLAN_VID.name(), new VlanVidDecoder());
70 decoderMap.put(Criterion.Type.VLAN_PCP.name(), new VlanPcpDecoder());
71 decoderMap.put(Criterion.Type.IP_DSCP.name(), new IpDscpDecoder());
72 decoderMap.put(Criterion.Type.IP_ECN.name(), new IpEcnDecoder());
73 decoderMap.put(Criterion.Type.IP_PROTO.name(), new IpProtoDecoder());
74 decoderMap.put(Criterion.Type.IPV4_SRC.name(), new IpV4SrcDecoder());
75 decoderMap.put(Criterion.Type.IPV4_DST.name(), new IpV4DstDecoder());
76 decoderMap.put(Criterion.Type.TCP_SRC.name(), new TcpSrcDecoder());
77 decoderMap.put(Criterion.Type.TCP_DST.name(), new TcpDstDecoder());
78 decoderMap.put(Criterion.Type.UDP_SRC.name(), new UdpSrcDecoder());
79 decoderMap.put(Criterion.Type.UDP_DST.name(), new UdpDstDecoder());
80 decoderMap.put(Criterion.Type.SCTP_SRC.name(), new SctpSrcDecoder());
81 decoderMap.put(Criterion.Type.SCTP_DST.name(), new SctpDstDecoder());
82 decoderMap.put(Criterion.Type.ICMPV4_TYPE.name(), new IcmpV4TypeDecoder());
83 decoderMap.put(Criterion.Type.ICMPV4_CODE.name(), new IcmpV4CodeDecoder());
84 decoderMap.put(Criterion.Type.IPV6_SRC.name(), new IpV6SrcDecoder());
85 decoderMap.put(Criterion.Type.IPV6_DST.name(), new IpV6DstDecoder());
86 decoderMap.put(Criterion.Type.IPV6_FLABEL.name(), new IpV6FLabelDecoder());
87 decoderMap.put(Criterion.Type.ICMPV6_TYPE.name(), new IcmpV6TypeDecoder());
88 decoderMap.put(Criterion.Type.ICMPV6_CODE.name(), new IcmpV6CodeDecoder());
89 decoderMap.put(Criterion.Type.IPV6_ND_TARGET.name(), new V6NDTargetDecoder());
90 decoderMap.put(Criterion.Type.IPV6_ND_SLL.name(), new V6NDSllDecoder());
91 decoderMap.put(Criterion.Type.IPV6_ND_TLL.name(), new V6NDTllDecoder());
92 decoderMap.put(Criterion.Type.MPLS_LABEL.name(), new MplsLabelDecoder());
93 decoderMap.put(Criterion.Type.IPV6_EXTHDR.name(), new IpV6ExthdrDecoder());
94 decoderMap.put(Criterion.Type.OCH_SIGID.name(), new OchSigIdDecoder());
95 decoderMap.put(Criterion.Type.OCH_SIGTYPE.name(), new OchSigTypeDecoder());
96 }
97
98 private class EthTypeDecoder implements CriterionDecoder {
99 @Override
100 public Criterion decodeCriterion(ObjectNode json) {
101 int ethType = nullIsIllegal(json.get(CriterionCodec.ETH_TYPE),
102 CriterionCodec.ETH_TYPE + MISSING_MEMBER_MESSAGE).asInt();
103 return Criteria.matchEthType(ethType);
104 }
105 }
106
107 private class EthDstDecoder implements CriterionDecoder {
108 @Override
109 public Criterion decodeCriterion(ObjectNode json) {
110 MacAddress mac = MacAddress.valueOf(nullIsIllegal(json.get(CriterionCodec.MAC),
111 CriterionCodec.MAC + MISSING_MEMBER_MESSAGE).asText());
112
113 return Criteria.matchEthDst(mac);
114 }
115 }
116
117 private class EthSrcDecoder implements CriterionDecoder {
118 @Override
119 public Criterion decodeCriterion(ObjectNode json) {
120 MacAddress mac = MacAddress.valueOf(nullIsIllegal(json.get(CriterionCodec.MAC),
121 CriterionCodec.MAC + MISSING_MEMBER_MESSAGE).asText());
122
123 return Criteria.matchEthSrc(mac);
124 }
125 }
126
127 private class InPortDecoder implements CriterionDecoder {
128 @Override
129 public Criterion decodeCriterion(ObjectNode json) {
130 PortNumber port = PortNumber.portNumber(nullIsIllegal(json.get(CriterionCodec.PORT),
131 CriterionCodec.PORT + MISSING_MEMBER_MESSAGE).asLong());
132
133 return Criteria.matchInPort(port);
134 }
135 }
136
137 private class InPhyPortDecoder implements CriterionDecoder {
138 @Override
139 public Criterion decodeCriterion(ObjectNode json) {
140 PortNumber port = PortNumber.portNumber(nullIsIllegal(json.get(CriterionCodec.PORT),
141 CriterionCodec.PORT + MISSING_MEMBER_MESSAGE).asLong());
142
143 return Criteria.matchInPhyPort(port);
144 }
145 }
146
147 private class MetadataDecoder implements CriterionDecoder {
148 @Override
149 public Criterion decodeCriterion(ObjectNode json) {
150 long metadata = nullIsIllegal(json.get(CriterionCodec.METADATA),
151 CriterionCodec.METADATA + MISSING_MEMBER_MESSAGE).asLong();
152
153 return Criteria.matchMetadata(metadata);
154 }
155 }
156
157 private class VlanVidDecoder implements CriterionDecoder {
158 @Override
159 public Criterion decodeCriterion(ObjectNode json) {
160 short vlanId = (short) nullIsIllegal(json.get(CriterionCodec.VLAN_ID),
161 CriterionCodec.VLAN_ID + MISSING_MEMBER_MESSAGE).asInt();
162
163 return Criteria.matchVlanId(VlanId.vlanId(vlanId));
164 }
165 }
166
167 private class VlanPcpDecoder implements CriterionDecoder {
168 @Override
169 public Criterion decodeCriterion(ObjectNode json) {
170 byte priority = (byte) nullIsIllegal(json.get(CriterionCodec.PRIORITY),
171 CriterionCodec.VLAN_ID + MISSING_MEMBER_MESSAGE).asInt();
172
173 return Criteria.matchVlanPcp(priority);
174 }
175 }
176
177 private class IpDscpDecoder implements CriterionDecoder {
178 @Override
179 public Criterion decodeCriterion(ObjectNode json) {
180 byte ipDscp = (byte) nullIsIllegal(json.get(CriterionCodec.IP_DSCP),
181 CriterionCodec.IP_DSCP + MISSING_MEMBER_MESSAGE).asInt();
182 return Criteria.matchIPDscp(ipDscp);
183 }
184 }
185
186 private class IpEcnDecoder implements CriterionDecoder {
187 @Override
188 public Criterion decodeCriterion(ObjectNode json) {
189 byte ipEcn = (byte) nullIsIllegal(json.get(CriterionCodec.IP_ECN),
190 CriterionCodec.IP_ECN + MISSING_MEMBER_MESSAGE).asInt();
191 return Criteria.matchIPEcn(ipEcn);
192 }
193 }
194
195 private class IpProtoDecoder implements CriterionDecoder {
196 @Override
197 public Criterion decodeCriterion(ObjectNode json) {
198 short proto = (short) nullIsIllegal(json.get(CriterionCodec.PROTOCOL),
199 CriterionCodec.PROTOCOL + MISSING_MEMBER_MESSAGE).asInt();
200 return Criteria.matchIPProtocol(proto);
201 }
202 }
203
204 private class IpV4SrcDecoder implements CriterionDecoder {
205 @Override
206 public Criterion decodeCriterion(ObjectNode json) {
207 String ip = nullIsIllegal(json.get(CriterionCodec.IP),
208 CriterionCodec.IP + MISSING_MEMBER_MESSAGE).asText();
209 return Criteria.matchIPSrc(IpPrefix.valueOf(ip));
210 }
211 }
212
213 private class IpV4DstDecoder implements CriterionDecoder {
214 @Override
215 public Criterion decodeCriterion(ObjectNode json) {
216 String ip = nullIsIllegal(json.get(CriterionCodec.IP),
217 CriterionCodec.IP + MISSING_MEMBER_MESSAGE).asText();
218 return Criteria.matchIPDst(IpPrefix.valueOf(ip));
219 }
220 }
221
222 private class IpV6SrcDecoder implements CriterionDecoder {
223 @Override
224 public Criterion decodeCriterion(ObjectNode json) {
225 String ip = nullIsIllegal(json.get(CriterionCodec.IP),
226 CriterionCodec.IP + MISSING_MEMBER_MESSAGE).asText();
227 return Criteria.matchIPv6Src(IpPrefix.valueOf(ip));
228 }
229 }
230
231 private class IpV6DstDecoder implements CriterionDecoder {
232 @Override
233 public Criterion decodeCriterion(ObjectNode json) {
234 String ip = nullIsIllegal(json.get(CriterionCodec.IP),
235 CriterionCodec.IP + MISSING_MEMBER_MESSAGE).asText();
236 return Criteria.matchIPv6Dst(IpPrefix.valueOf(ip));
237 }
238 }
239
240 private class TcpSrcDecoder implements CriterionDecoder {
241 @Override
242 public Criterion decodeCriterion(ObjectNode json) {
243 int tcpPort = nullIsIllegal(json.get(CriterionCodec.TCP_PORT),
244 CriterionCodec.TCP_PORT + MISSING_MEMBER_MESSAGE).asInt();
245 return Criteria.matchTcpSrc(tcpPort);
246 }
247 }
248
249 private class TcpDstDecoder implements CriterionDecoder {
250 @Override
251 public Criterion decodeCriterion(ObjectNode json) {
252 int tcpPort = nullIsIllegal(json.get(CriterionCodec.TCP_PORT),
253 CriterionCodec.TCP_PORT + MISSING_MEMBER_MESSAGE).asInt();
254 return Criteria.matchTcpDst(tcpPort);
255 }
256 }
257
258 private class UdpSrcDecoder implements CriterionDecoder {
259 @Override
260 public Criterion decodeCriterion(ObjectNode json) {
261 int udpPort = nullIsIllegal(json.get(CriterionCodec.UDP_PORT),
262 CriterionCodec.UDP_PORT + MISSING_MEMBER_MESSAGE).asInt();
263 return Criteria.matchUdpSrc(udpPort);
264 }
265 }
266
267 private class UdpDstDecoder implements CriterionDecoder {
268 @Override
269 public Criterion decodeCriterion(ObjectNode json) {
270 int udpPort = nullIsIllegal(json.get(CriterionCodec.UDP_PORT),
271 CriterionCodec.UDP_PORT + MISSING_MEMBER_MESSAGE).asInt();
272 return Criteria.matchUdpDst(udpPort);
273 }
274 }
275
276 private class SctpSrcDecoder implements CriterionDecoder {
277 @Override
278 public Criterion decodeCriterion(ObjectNode json) {
279 int sctpPort = nullIsIllegal(json.get(CriterionCodec.SCTP_PORT),
280 CriterionCodec.SCTP_PORT + MISSING_MEMBER_MESSAGE).asInt();
281 return Criteria.matchSctpSrc(sctpPort);
282 }
283 }
284
285 private class SctpDstDecoder implements CriterionDecoder {
286 @Override
287 public Criterion decodeCriterion(ObjectNode json) {
288 int sctpPort = nullIsIllegal(json.get(CriterionCodec.SCTP_PORT),
289 CriterionCodec.SCTP_PORT + MISSING_MEMBER_MESSAGE).asInt();
290 return Criteria.matchSctpDst(sctpPort);
291 }
292 }
293
294 private class IcmpV4TypeDecoder implements CriterionDecoder {
295 @Override
296 public Criterion decodeCriterion(ObjectNode json) {
297 short type = (short) nullIsIllegal(json.get(CriterionCodec.ICMP_TYPE),
298 CriterionCodec.ICMP_TYPE + MISSING_MEMBER_MESSAGE).asInt();
299 return Criteria.matchIcmpType(type);
300 }
301 }
302
303 private class IcmpV4CodeDecoder implements CriterionDecoder {
304 @Override
305 public Criterion decodeCriterion(ObjectNode json) {
306 short code = (short) nullIsIllegal(json.get(CriterionCodec.ICMP_CODE),
307 CriterionCodec.ICMP_CODE + MISSING_MEMBER_MESSAGE).asInt();
308 return Criteria.matchIcmpCode(code);
309 }
310 }
311
312 private class IpV6FLabelDecoder implements CriterionDecoder {
313 @Override
314 public Criterion decodeCriterion(ObjectNode json) {
315 int flowLabel = nullIsIllegal(json.get(CriterionCodec.FLOW_LABEL),
316 CriterionCodec.FLOW_LABEL + MISSING_MEMBER_MESSAGE).asInt();
317 return Criteria.matchIPv6FlowLabel(flowLabel);
318 }
319 }
320
321 private class IcmpV6TypeDecoder implements CriterionDecoder {
322 @Override
323 public Criterion decodeCriterion(ObjectNode json) {
324 short type = (short) nullIsIllegal(json.get(CriterionCodec.ICMPV6_TYPE),
325 CriterionCodec.ICMPV6_TYPE + MISSING_MEMBER_MESSAGE).asInt();
326 return Criteria.matchIcmpv6Type(type);
327 }
328 }
329
330 private class IcmpV6CodeDecoder implements CriterionDecoder {
331 @Override
332 public Criterion decodeCriterion(ObjectNode json) {
333 short code = (short) nullIsIllegal(json.get(CriterionCodec.ICMPV6_CODE),
334 CriterionCodec.ICMPV6_CODE + MISSING_MEMBER_MESSAGE).asInt();
335 return Criteria.matchIcmpv6Code(code);
336 }
337 }
338
339 private class V6NDTargetDecoder implements CriterionDecoder {
340 @Override
341 public Criterion decodeCriterion(ObjectNode json) {
342 Ip6Address target = Ip6Address.valueOf(nullIsIllegal(json.get(CriterionCodec.TARGET_ADDRESS),
343 CriterionCodec.TARGET_ADDRESS + MISSING_MEMBER_MESSAGE).asText());
344 return Criteria.matchIPv6NDTargetAddress(target);
345 }
346 }
347
348 private class V6NDSllDecoder implements CriterionDecoder {
349 @Override
350 public Criterion decodeCriterion(ObjectNode json) {
351 MacAddress mac = MacAddress.valueOf(nullIsIllegal(json.get(CriterionCodec.MAC),
352 CriterionCodec.MAC + MISSING_MEMBER_MESSAGE).asText());
353 return Criteria.matchIPv6NDSourceLinkLayerAddress(mac);
354 }
355 }
356
357 private class V6NDTllDecoder implements CriterionDecoder {
358 @Override
359 public Criterion decodeCriterion(ObjectNode json) {
360 MacAddress mac = MacAddress.valueOf(nullIsIllegal(json.get(CriterionCodec.MAC),
361 CriterionCodec.MAC + MISSING_MEMBER_MESSAGE).asText());
362 return Criteria.matchIPv6NDTargetLinkLayerAddress(mac);
363 }
364 }
365
366 private class MplsLabelDecoder implements CriterionDecoder {
367 @Override
368 public Criterion decodeCriterion(ObjectNode json) {
369 int label = nullIsIllegal(json.get(CriterionCodec.LABEL),
370 CriterionCodec.LABEL + MISSING_MEMBER_MESSAGE).asInt();
371 return Criteria.matchMplsLabel(MplsLabel.mplsLabel(label));
372 }
373 }
374
375 private class IpV6ExthdrDecoder implements CriterionDecoder {
376 @Override
377 public Criterion decodeCriterion(ObjectNode json) {
378 int exthdrFlags = nullIsIllegal(json.get(CriterionCodec.EXT_HDR_FLAGS),
379 CriterionCodec.EXT_HDR_FLAGS + MISSING_MEMBER_MESSAGE).asInt();
380 return Criteria.matchIPv6ExthdrFlags(exthdrFlags);
381 }
382 }
383
384 private class OchSigIdDecoder implements CriterionDecoder {
385 @Override
386 public Criterion decodeCriterion(ObjectNode json) {
387 if (json.get(CriterionCodec.LAMBDA) != null) {
388 Lambda lambda = Lambda.indexedLambda(nullIsIllegal(json.get(CriterionCodec.LAMBDA),
389 CriterionCodec.LAMBDA + MISSING_MEMBER_MESSAGE).asInt());
390 return Criteria.matchLambda(lambda);
391 } else {
392 JsonNode ochSignalId = nullIsIllegal(json.get(CriterionCodec.OCH_SIGNAL_ID),
393 CriterionCodec.GRID_TYPE + MISSING_MEMBER_MESSAGE);
394 GridType gridType =
395 GridType.valueOf(
396 nullIsIllegal(ochSignalId.get(CriterionCodec.GRID_TYPE),
397 CriterionCodec.GRID_TYPE + MISSING_MEMBER_MESSAGE).asText());
398 ChannelSpacing channelSpacing =
399 ChannelSpacing.valueOf(
400 nullIsIllegal(ochSignalId.get(CriterionCodec.CHANNEL_SPACING),
401 CriterionCodec.CHANNEL_SPACING + MISSING_MEMBER_MESSAGE).asText());
402 int spacingMultiplier = nullIsIllegal(ochSignalId.get(CriterionCodec.SPACING_MULIPLIER),
403 CriterionCodec.SPACING_MULIPLIER + MISSING_MEMBER_MESSAGE).asInt();
404 int slotGranularity = nullIsIllegal(ochSignalId.get(CriterionCodec.SLOT_GRANULARITY),
405 CriterionCodec.SLOT_GRANULARITY + MISSING_MEMBER_MESSAGE).asInt();
406 return Criteria.matchLambda(
407 Lambda.ochSignal(gridType, channelSpacing,
408 spacingMultiplier, slotGranularity));
409 }
410 }
411 }
412
413 private class OchSigTypeDecoder implements CriterionDecoder {
414 @Override
415 public Criterion decodeCriterion(ObjectNode json) {
416 return null;
417 }
418 }
419
420 /**
421 * Decodes the JSON into a criterion object.
422 *
423 * @return Criterion object
424 * @throws IllegalArgumentException if the JSON is invalid
425 */
426 public Criterion decode() {
427 String type = json.get(CriterionCodec.TYPE).asText();
428
429 CriterionDecoder decoder = decoderMap.get(type);
430 if (decoder != null) {
431 return decoder.decodeCriterion(json);
432 }
433
434 throw new IllegalArgumentException("Type " + type + " is unknown");
435 }
436
437
438}