blob: e5f8896a04c6a8947a858b8986792b8c20e9ce0b [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 */
Ray Milkey6d7968e2015-07-06 14:30:02 -070041public final class DecodeCriterionCodecHelper {
Ray Milkeyd43fe452015-05-29 09:35:12 -070042
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 */
Ray Milkey6d7968e2015-07-06 14:30:02 -070059 public DecodeCriterionCodecHelper(ObjectNode json) {
Ray Milkeyd43fe452015-05-29 09:35:12 -070060 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());
Hyunsun Moon7080a0d2015-08-14 19:18:48 -070096 decoderMap.put(Criterion.Type.TUNNEL_ID.name(), new TunnelIdDecoder());
Ray Milkeyd43fe452015-05-29 09:35:12 -070097 }
98
99 private class EthTypeDecoder implements CriterionDecoder {
100 @Override
101 public Criterion decodeCriterion(ObjectNode json) {
102 int ethType = nullIsIllegal(json.get(CriterionCodec.ETH_TYPE),
103 CriterionCodec.ETH_TYPE + MISSING_MEMBER_MESSAGE).asInt();
104 return Criteria.matchEthType(ethType);
105 }
106 }
107
108 private class EthDstDecoder implements CriterionDecoder {
109 @Override
110 public Criterion decodeCriterion(ObjectNode json) {
111 MacAddress mac = MacAddress.valueOf(nullIsIllegal(json.get(CriterionCodec.MAC),
112 CriterionCodec.MAC + MISSING_MEMBER_MESSAGE).asText());
113
114 return Criteria.matchEthDst(mac);
115 }
116 }
117
118 private class EthSrcDecoder implements CriterionDecoder {
119 @Override
120 public Criterion decodeCriterion(ObjectNode json) {
121 MacAddress mac = MacAddress.valueOf(nullIsIllegal(json.get(CriterionCodec.MAC),
122 CriterionCodec.MAC + MISSING_MEMBER_MESSAGE).asText());
123
124 return Criteria.matchEthSrc(mac);
125 }
126 }
127
128 private class InPortDecoder implements CriterionDecoder {
129 @Override
130 public Criterion decodeCriterion(ObjectNode json) {
131 PortNumber port = PortNumber.portNumber(nullIsIllegal(json.get(CriterionCodec.PORT),
132 CriterionCodec.PORT + MISSING_MEMBER_MESSAGE).asLong());
133
134 return Criteria.matchInPort(port);
135 }
136 }
137
138 private class InPhyPortDecoder implements CriterionDecoder {
139 @Override
140 public Criterion decodeCriterion(ObjectNode json) {
141 PortNumber port = PortNumber.portNumber(nullIsIllegal(json.get(CriterionCodec.PORT),
142 CriterionCodec.PORT + MISSING_MEMBER_MESSAGE).asLong());
143
144 return Criteria.matchInPhyPort(port);
145 }
146 }
147
148 private class MetadataDecoder implements CriterionDecoder {
149 @Override
150 public Criterion decodeCriterion(ObjectNode json) {
151 long metadata = nullIsIllegal(json.get(CriterionCodec.METADATA),
152 CriterionCodec.METADATA + MISSING_MEMBER_MESSAGE).asLong();
153
154 return Criteria.matchMetadata(metadata);
155 }
156 }
157
158 private class VlanVidDecoder implements CriterionDecoder {
159 @Override
160 public Criterion decodeCriterion(ObjectNode json) {
161 short vlanId = (short) nullIsIllegal(json.get(CriterionCodec.VLAN_ID),
162 CriterionCodec.VLAN_ID + MISSING_MEMBER_MESSAGE).asInt();
163
164 return Criteria.matchVlanId(VlanId.vlanId(vlanId));
165 }
166 }
167
168 private class VlanPcpDecoder implements CriterionDecoder {
169 @Override
170 public Criterion decodeCriterion(ObjectNode json) {
171 byte priority = (byte) nullIsIllegal(json.get(CriterionCodec.PRIORITY),
172 CriterionCodec.VLAN_ID + MISSING_MEMBER_MESSAGE).asInt();
173
174 return Criteria.matchVlanPcp(priority);
175 }
176 }
177
178 private class IpDscpDecoder implements CriterionDecoder {
179 @Override
180 public Criterion decodeCriterion(ObjectNode json) {
181 byte ipDscp = (byte) nullIsIllegal(json.get(CriterionCodec.IP_DSCP),
182 CriterionCodec.IP_DSCP + MISSING_MEMBER_MESSAGE).asInt();
183 return Criteria.matchIPDscp(ipDscp);
184 }
185 }
186
187 private class IpEcnDecoder implements CriterionDecoder {
188 @Override
189 public Criterion decodeCriterion(ObjectNode json) {
190 byte ipEcn = (byte) nullIsIllegal(json.get(CriterionCodec.IP_ECN),
191 CriterionCodec.IP_ECN + MISSING_MEMBER_MESSAGE).asInt();
192 return Criteria.matchIPEcn(ipEcn);
193 }
194 }
195
196 private class IpProtoDecoder implements CriterionDecoder {
197 @Override
198 public Criterion decodeCriterion(ObjectNode json) {
199 short proto = (short) nullIsIllegal(json.get(CriterionCodec.PROTOCOL),
200 CriterionCodec.PROTOCOL + MISSING_MEMBER_MESSAGE).asInt();
201 return Criteria.matchIPProtocol(proto);
202 }
203 }
204
205 private class IpV4SrcDecoder implements CriterionDecoder {
206 @Override
207 public Criterion decodeCriterion(ObjectNode json) {
208 String ip = nullIsIllegal(json.get(CriterionCodec.IP),
209 CriterionCodec.IP + MISSING_MEMBER_MESSAGE).asText();
210 return Criteria.matchIPSrc(IpPrefix.valueOf(ip));
211 }
212 }
213
214 private class IpV4DstDecoder implements CriterionDecoder {
215 @Override
216 public Criterion decodeCriterion(ObjectNode json) {
217 String ip = nullIsIllegal(json.get(CriterionCodec.IP),
218 CriterionCodec.IP + MISSING_MEMBER_MESSAGE).asText();
219 return Criteria.matchIPDst(IpPrefix.valueOf(ip));
220 }
221 }
222
223 private class IpV6SrcDecoder implements CriterionDecoder {
224 @Override
225 public Criterion decodeCriterion(ObjectNode json) {
226 String ip = nullIsIllegal(json.get(CriterionCodec.IP),
227 CriterionCodec.IP + MISSING_MEMBER_MESSAGE).asText();
228 return Criteria.matchIPv6Src(IpPrefix.valueOf(ip));
229 }
230 }
231
232 private class IpV6DstDecoder implements CriterionDecoder {
233 @Override
234 public Criterion decodeCriterion(ObjectNode json) {
235 String ip = nullIsIllegal(json.get(CriterionCodec.IP),
236 CriterionCodec.IP + MISSING_MEMBER_MESSAGE).asText();
237 return Criteria.matchIPv6Dst(IpPrefix.valueOf(ip));
238 }
239 }
240
241 private class TcpSrcDecoder implements CriterionDecoder {
242 @Override
243 public Criterion decodeCriterion(ObjectNode json) {
244 int tcpPort = nullIsIllegal(json.get(CriterionCodec.TCP_PORT),
245 CriterionCodec.TCP_PORT + MISSING_MEMBER_MESSAGE).asInt();
246 return Criteria.matchTcpSrc(tcpPort);
247 }
248 }
249
250 private class TcpDstDecoder implements CriterionDecoder {
251 @Override
252 public Criterion decodeCriterion(ObjectNode json) {
253 int tcpPort = nullIsIllegal(json.get(CriterionCodec.TCP_PORT),
254 CriterionCodec.TCP_PORT + MISSING_MEMBER_MESSAGE).asInt();
255 return Criteria.matchTcpDst(tcpPort);
256 }
257 }
258
259 private class UdpSrcDecoder implements CriterionDecoder {
260 @Override
261 public Criterion decodeCriterion(ObjectNode json) {
262 int udpPort = nullIsIllegal(json.get(CriterionCodec.UDP_PORT),
263 CriterionCodec.UDP_PORT + MISSING_MEMBER_MESSAGE).asInt();
264 return Criteria.matchUdpSrc(udpPort);
265 }
266 }
267
268 private class UdpDstDecoder implements CriterionDecoder {
269 @Override
270 public Criterion decodeCriterion(ObjectNode json) {
271 int udpPort = nullIsIllegal(json.get(CriterionCodec.UDP_PORT),
272 CriterionCodec.UDP_PORT + MISSING_MEMBER_MESSAGE).asInt();
273 return Criteria.matchUdpDst(udpPort);
274 }
275 }
276
277 private class SctpSrcDecoder implements CriterionDecoder {
278 @Override
279 public Criterion decodeCriterion(ObjectNode json) {
280 int sctpPort = nullIsIllegal(json.get(CriterionCodec.SCTP_PORT),
281 CriterionCodec.SCTP_PORT + MISSING_MEMBER_MESSAGE).asInt();
282 return Criteria.matchSctpSrc(sctpPort);
283 }
284 }
285
286 private class SctpDstDecoder implements CriterionDecoder {
287 @Override
288 public Criterion decodeCriterion(ObjectNode json) {
289 int sctpPort = nullIsIllegal(json.get(CriterionCodec.SCTP_PORT),
290 CriterionCodec.SCTP_PORT + MISSING_MEMBER_MESSAGE).asInt();
291 return Criteria.matchSctpDst(sctpPort);
292 }
293 }
294
295 private class IcmpV4TypeDecoder implements CriterionDecoder {
296 @Override
297 public Criterion decodeCriterion(ObjectNode json) {
298 short type = (short) nullIsIllegal(json.get(CriterionCodec.ICMP_TYPE),
299 CriterionCodec.ICMP_TYPE + MISSING_MEMBER_MESSAGE).asInt();
300 return Criteria.matchIcmpType(type);
301 }
302 }
303
304 private class IcmpV4CodeDecoder implements CriterionDecoder {
305 @Override
306 public Criterion decodeCriterion(ObjectNode json) {
307 short code = (short) nullIsIllegal(json.get(CriterionCodec.ICMP_CODE),
308 CriterionCodec.ICMP_CODE + MISSING_MEMBER_MESSAGE).asInt();
309 return Criteria.matchIcmpCode(code);
310 }
311 }
312
313 private class IpV6FLabelDecoder implements CriterionDecoder {
314 @Override
315 public Criterion decodeCriterion(ObjectNode json) {
316 int flowLabel = nullIsIllegal(json.get(CriterionCodec.FLOW_LABEL),
317 CriterionCodec.FLOW_LABEL + MISSING_MEMBER_MESSAGE).asInt();
318 return Criteria.matchIPv6FlowLabel(flowLabel);
319 }
320 }
321
322 private class IcmpV6TypeDecoder implements CriterionDecoder {
323 @Override
324 public Criterion decodeCriterion(ObjectNode json) {
325 short type = (short) nullIsIllegal(json.get(CriterionCodec.ICMPV6_TYPE),
326 CriterionCodec.ICMPV6_TYPE + MISSING_MEMBER_MESSAGE).asInt();
327 return Criteria.matchIcmpv6Type(type);
328 }
329 }
330
331 private class IcmpV6CodeDecoder implements CriterionDecoder {
332 @Override
333 public Criterion decodeCriterion(ObjectNode json) {
334 short code = (short) nullIsIllegal(json.get(CriterionCodec.ICMPV6_CODE),
335 CriterionCodec.ICMPV6_CODE + MISSING_MEMBER_MESSAGE).asInt();
336 return Criteria.matchIcmpv6Code(code);
337 }
338 }
339
340 private class V6NDTargetDecoder implements CriterionDecoder {
341 @Override
342 public Criterion decodeCriterion(ObjectNode json) {
343 Ip6Address target = Ip6Address.valueOf(nullIsIllegal(json.get(CriterionCodec.TARGET_ADDRESS),
344 CriterionCodec.TARGET_ADDRESS + MISSING_MEMBER_MESSAGE).asText());
345 return Criteria.matchIPv6NDTargetAddress(target);
346 }
347 }
348
349 private class V6NDSllDecoder implements CriterionDecoder {
350 @Override
351 public Criterion decodeCriterion(ObjectNode json) {
352 MacAddress mac = MacAddress.valueOf(nullIsIllegal(json.get(CriterionCodec.MAC),
353 CriterionCodec.MAC + MISSING_MEMBER_MESSAGE).asText());
354 return Criteria.matchIPv6NDSourceLinkLayerAddress(mac);
355 }
356 }
357
358 private class V6NDTllDecoder implements CriterionDecoder {
359 @Override
360 public Criterion decodeCriterion(ObjectNode json) {
361 MacAddress mac = MacAddress.valueOf(nullIsIllegal(json.get(CriterionCodec.MAC),
362 CriterionCodec.MAC + MISSING_MEMBER_MESSAGE).asText());
363 return Criteria.matchIPv6NDTargetLinkLayerAddress(mac);
364 }
365 }
366
367 private class MplsLabelDecoder implements CriterionDecoder {
368 @Override
369 public Criterion decodeCriterion(ObjectNode json) {
370 int label = nullIsIllegal(json.get(CriterionCodec.LABEL),
371 CriterionCodec.LABEL + MISSING_MEMBER_MESSAGE).asInt();
372 return Criteria.matchMplsLabel(MplsLabel.mplsLabel(label));
373 }
374 }
375
376 private class IpV6ExthdrDecoder implements CriterionDecoder {
377 @Override
378 public Criterion decodeCriterion(ObjectNode json) {
379 int exthdrFlags = nullIsIllegal(json.get(CriterionCodec.EXT_HDR_FLAGS),
380 CriterionCodec.EXT_HDR_FLAGS + MISSING_MEMBER_MESSAGE).asInt();
381 return Criteria.matchIPv6ExthdrFlags(exthdrFlags);
382 }
383 }
384
385 private class OchSigIdDecoder implements CriterionDecoder {
386 @Override
387 public Criterion decodeCriterion(ObjectNode json) {
388 if (json.get(CriterionCodec.LAMBDA) != null) {
389 Lambda lambda = Lambda.indexedLambda(nullIsIllegal(json.get(CriterionCodec.LAMBDA),
390 CriterionCodec.LAMBDA + MISSING_MEMBER_MESSAGE).asInt());
391 return Criteria.matchLambda(lambda);
392 } else {
393 JsonNode ochSignalId = nullIsIllegal(json.get(CriterionCodec.OCH_SIGNAL_ID),
394 CriterionCodec.GRID_TYPE + MISSING_MEMBER_MESSAGE);
395 GridType gridType =
396 GridType.valueOf(
397 nullIsIllegal(ochSignalId.get(CriterionCodec.GRID_TYPE),
398 CriterionCodec.GRID_TYPE + MISSING_MEMBER_MESSAGE).asText());
399 ChannelSpacing channelSpacing =
400 ChannelSpacing.valueOf(
401 nullIsIllegal(ochSignalId.get(CriterionCodec.CHANNEL_SPACING),
402 CriterionCodec.CHANNEL_SPACING + MISSING_MEMBER_MESSAGE).asText());
403 int spacingMultiplier = nullIsIllegal(ochSignalId.get(CriterionCodec.SPACING_MULIPLIER),
404 CriterionCodec.SPACING_MULIPLIER + MISSING_MEMBER_MESSAGE).asInt();
405 int slotGranularity = nullIsIllegal(ochSignalId.get(CriterionCodec.SLOT_GRANULARITY),
406 CriterionCodec.SLOT_GRANULARITY + MISSING_MEMBER_MESSAGE).asInt();
407 return Criteria.matchLambda(
408 Lambda.ochSignal(gridType, channelSpacing,
409 spacingMultiplier, slotGranularity));
410 }
411 }
412 }
413
414 private class OchSigTypeDecoder implements CriterionDecoder {
415 @Override
416 public Criterion decodeCriterion(ObjectNode json) {
417 return null;
418 }
419 }
420
Hyunsun Moon7080a0d2015-08-14 19:18:48 -0700421 private class TunnelIdDecoder implements CriterionDecoder {
422 @Override
423 public Criterion decodeCriterion(ObjectNode json) {
424 long tunnelId = nullIsIllegal(json.get(CriterionCodec.TUNNEL_ID),
425 CriterionCodec.TUNNEL_ID + MISSING_MEMBER_MESSAGE).asLong();
426 return Criteria.matchTunnelId(tunnelId);
427 }
428 }
429
Ray Milkeyd43fe452015-05-29 09:35:12 -0700430 /**
431 * Decodes the JSON into a criterion object.
432 *
433 * @return Criterion object
434 * @throws IllegalArgumentException if the JSON is invalid
435 */
436 public Criterion decode() {
437 String type = json.get(CriterionCodec.TYPE).asText();
438
439 CriterionDecoder decoder = decoderMap.get(type);
440 if (decoder != null) {
441 return decoder.decodeCriterion(json);
442 }
443
444 throw new IllegalArgumentException("Type " + type + " is unknown");
445 }
446
447
448}