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 java.util.HashMap;
21 import org.onlab.packet.Ip6Address;
22 import org.onlab.packet.IpPrefix;
23 import org.onlab.packet.MacAddress;
24 import org.onlab.packet.MplsLabel;
25 import org.onlab.packet.TpPort;
26 import org.onlab.packet.VlanId;
27 import org.onosproject.net.ChannelSpacing;
28 import org.onosproject.net.GridType;
29 import org.onosproject.net.Lambda;
30 import org.onosproject.net.PortNumber;
31 import org.onosproject.net.flow.criteria.Criteria;
32 import org.onosproject.net.flow.criteria.Criterion;
34 import com.fasterxml.jackson.databind.JsonNode;
35 import com.fasterxml.jackson.databind.node.ObjectNode;
37 import static org.onlab.util.Tools.nullIsIllegal;
40 * Decode portion of the criterion codec.
42 public final class DecodeCriterionCodecHelper {
44 private final ObjectNode json;
46 protected static final String MISSING_MEMBER_MESSAGE =
47 " member is required in Criterion";
49 private interface CriterionDecoder {
50 Criterion decodeCriterion(ObjectNode json);
52 private final Map<String, CriterionDecoder> decoderMap;
55 * Creates a decode criterion codec object.
56 * Initializes the lookup map for criterion subclass decoders.
58 * @param json JSON object to decode
60 public DecodeCriterionCodecHelper(ObjectNode json) {
62 decoderMap = new HashMap<>();
64 decoderMap.put(Criterion.Type.IN_PORT.name(), new InPortDecoder());
65 decoderMap.put(Criterion.Type.IN_PHY_PORT.name(), new InPhyPortDecoder());
66 decoderMap.put(Criterion.Type.METADATA.name(), new MetadataDecoder());
67 decoderMap.put(Criterion.Type.ETH_DST.name(), new EthDstDecoder());
68 decoderMap.put(Criterion.Type.ETH_SRC.name(), new EthSrcDecoder());
69 decoderMap.put(Criterion.Type.ETH_TYPE.name(), new EthTypeDecoder());
70 decoderMap.put(Criterion.Type.VLAN_VID.name(), new VlanVidDecoder());
71 decoderMap.put(Criterion.Type.VLAN_PCP.name(), new VlanPcpDecoder());
72 decoderMap.put(Criterion.Type.IP_DSCP.name(), new IpDscpDecoder());
73 decoderMap.put(Criterion.Type.IP_ECN.name(), new IpEcnDecoder());
74 decoderMap.put(Criterion.Type.IP_PROTO.name(), new IpProtoDecoder());
75 decoderMap.put(Criterion.Type.IPV4_SRC.name(), new IpV4SrcDecoder());
76 decoderMap.put(Criterion.Type.IPV4_DST.name(), new IpV4DstDecoder());
77 decoderMap.put(Criterion.Type.TCP_SRC.name(), new TcpSrcDecoder());
78 decoderMap.put(Criterion.Type.TCP_DST.name(), new TcpDstDecoder());
79 decoderMap.put(Criterion.Type.UDP_SRC.name(), new UdpSrcDecoder());
80 decoderMap.put(Criterion.Type.UDP_DST.name(), new UdpDstDecoder());
81 decoderMap.put(Criterion.Type.SCTP_SRC.name(), new SctpSrcDecoder());
82 decoderMap.put(Criterion.Type.SCTP_DST.name(), new SctpDstDecoder());
83 decoderMap.put(Criterion.Type.ICMPV4_TYPE.name(), new IcmpV4TypeDecoder());
84 decoderMap.put(Criterion.Type.ICMPV4_CODE.name(), new IcmpV4CodeDecoder());
85 decoderMap.put(Criterion.Type.IPV6_SRC.name(), new IpV6SrcDecoder());
86 decoderMap.put(Criterion.Type.IPV6_DST.name(), new IpV6DstDecoder());
87 decoderMap.put(Criterion.Type.IPV6_FLABEL.name(), new IpV6FLabelDecoder());
88 decoderMap.put(Criterion.Type.ICMPV6_TYPE.name(), new IcmpV6TypeDecoder());
89 decoderMap.put(Criterion.Type.ICMPV6_CODE.name(), new IcmpV6CodeDecoder());
90 decoderMap.put(Criterion.Type.IPV6_ND_TARGET.name(), new V6NDTargetDecoder());
91 decoderMap.put(Criterion.Type.IPV6_ND_SLL.name(), new V6NDSllDecoder());
92 decoderMap.put(Criterion.Type.IPV6_ND_TLL.name(), new V6NDTllDecoder());
93 decoderMap.put(Criterion.Type.MPLS_LABEL.name(), new MplsLabelDecoder());
94 decoderMap.put(Criterion.Type.IPV6_EXTHDR.name(), new IpV6ExthdrDecoder());
95 decoderMap.put(Criterion.Type.OCH_SIGID.name(), new OchSigIdDecoder());
96 decoderMap.put(Criterion.Type.OCH_SIGTYPE.name(), new OchSigTypeDecoder());
97 decoderMap.put(Criterion.Type.TUNNEL_ID.name(), new TunnelIdDecoder());
100 private class EthTypeDecoder implements CriterionDecoder {
102 public Criterion decodeCriterion(ObjectNode json) {
103 int ethType = nullIsIllegal(json.get(CriterionCodec.ETH_TYPE),
104 CriterionCodec.ETH_TYPE + MISSING_MEMBER_MESSAGE).asInt();
105 return Criteria.matchEthType(ethType);
109 private class EthDstDecoder implements CriterionDecoder {
111 public Criterion decodeCriterion(ObjectNode json) {
112 MacAddress mac = MacAddress.valueOf(nullIsIllegal(json.get(CriterionCodec.MAC),
113 CriterionCodec.MAC + MISSING_MEMBER_MESSAGE).asText());
115 return Criteria.matchEthDst(mac);
119 private class EthSrcDecoder implements CriterionDecoder {
121 public Criterion decodeCriterion(ObjectNode json) {
122 MacAddress mac = MacAddress.valueOf(nullIsIllegal(json.get(CriterionCodec.MAC),
123 CriterionCodec.MAC + MISSING_MEMBER_MESSAGE).asText());
125 return Criteria.matchEthSrc(mac);
129 private class InPortDecoder implements CriterionDecoder {
131 public Criterion decodeCriterion(ObjectNode json) {
132 PortNumber port = PortNumber.portNumber(nullIsIllegal(json.get(CriterionCodec.PORT),
133 CriterionCodec.PORT + MISSING_MEMBER_MESSAGE).asLong());
135 return Criteria.matchInPort(port);
139 private class InPhyPortDecoder implements CriterionDecoder {
141 public Criterion decodeCriterion(ObjectNode json) {
142 PortNumber port = PortNumber.portNumber(nullIsIllegal(json.get(CriterionCodec.PORT),
143 CriterionCodec.PORT + MISSING_MEMBER_MESSAGE).asLong());
145 return Criteria.matchInPhyPort(port);
149 private class MetadataDecoder implements CriterionDecoder {
151 public Criterion decodeCriterion(ObjectNode json) {
152 long metadata = nullIsIllegal(json.get(CriterionCodec.METADATA),
153 CriterionCodec.METADATA + MISSING_MEMBER_MESSAGE).asLong();
155 return Criteria.matchMetadata(metadata);
159 private class VlanVidDecoder implements CriterionDecoder {
161 public Criterion decodeCriterion(ObjectNode json) {
162 short vlanId = (short) nullIsIllegal(json.get(CriterionCodec.VLAN_ID),
163 CriterionCodec.VLAN_ID + MISSING_MEMBER_MESSAGE).asInt();
165 return Criteria.matchVlanId(VlanId.vlanId(vlanId));
169 private class VlanPcpDecoder implements CriterionDecoder {
171 public Criterion decodeCriterion(ObjectNode json) {
172 byte priority = (byte) nullIsIllegal(json.get(CriterionCodec.PRIORITY),
173 CriterionCodec.VLAN_ID + MISSING_MEMBER_MESSAGE).asInt();
175 return Criteria.matchVlanPcp(priority);
179 private class IpDscpDecoder implements CriterionDecoder {
181 public Criterion decodeCriterion(ObjectNode json) {
182 byte ipDscp = (byte) nullIsIllegal(json.get(CriterionCodec.IP_DSCP),
183 CriterionCodec.IP_DSCP + MISSING_MEMBER_MESSAGE).asInt();
184 return Criteria.matchIPDscp(ipDscp);
188 private class IpEcnDecoder implements CriterionDecoder {
190 public Criterion decodeCriterion(ObjectNode json) {
191 byte ipEcn = (byte) nullIsIllegal(json.get(CriterionCodec.IP_ECN),
192 CriterionCodec.IP_ECN + MISSING_MEMBER_MESSAGE).asInt();
193 return Criteria.matchIPEcn(ipEcn);
197 private class IpProtoDecoder implements CriterionDecoder {
199 public Criterion decodeCriterion(ObjectNode json) {
200 short proto = (short) nullIsIllegal(json.get(CriterionCodec.PROTOCOL),
201 CriterionCodec.PROTOCOL + MISSING_MEMBER_MESSAGE).asInt();
202 return Criteria.matchIPProtocol(proto);
206 private class IpV4SrcDecoder implements CriterionDecoder {
208 public Criterion decodeCriterion(ObjectNode json) {
209 String ip = nullIsIllegal(json.get(CriterionCodec.IP),
210 CriterionCodec.IP + MISSING_MEMBER_MESSAGE).asText();
211 return Criteria.matchIPSrc(IpPrefix.valueOf(ip));
215 private class IpV4DstDecoder implements CriterionDecoder {
217 public Criterion decodeCriterion(ObjectNode json) {
218 String ip = nullIsIllegal(json.get(CriterionCodec.IP),
219 CriterionCodec.IP + MISSING_MEMBER_MESSAGE).asText();
220 return Criteria.matchIPDst(IpPrefix.valueOf(ip));
224 private class IpV6SrcDecoder implements CriterionDecoder {
226 public Criterion decodeCriterion(ObjectNode json) {
227 String ip = nullIsIllegal(json.get(CriterionCodec.IP),
228 CriterionCodec.IP + MISSING_MEMBER_MESSAGE).asText();
229 return Criteria.matchIPv6Src(IpPrefix.valueOf(ip));
233 private class IpV6DstDecoder implements CriterionDecoder {
235 public Criterion decodeCriterion(ObjectNode json) {
236 String ip = nullIsIllegal(json.get(CriterionCodec.IP),
237 CriterionCodec.IP + MISSING_MEMBER_MESSAGE).asText();
238 return Criteria.matchIPv6Dst(IpPrefix.valueOf(ip));
242 private class TcpSrcDecoder implements CriterionDecoder {
244 public Criterion decodeCriterion(ObjectNode json) {
245 TpPort tcpPort = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.TCP_PORT),
246 CriterionCodec.TCP_PORT + MISSING_MEMBER_MESSAGE).asInt());
247 return Criteria.matchTcpSrc(tcpPort);
251 private class TcpDstDecoder implements CriterionDecoder {
253 public Criterion decodeCriterion(ObjectNode json) {
254 TpPort tcpPort = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.TCP_PORT),
255 CriterionCodec.TCP_PORT + MISSING_MEMBER_MESSAGE).asInt());
256 return Criteria.matchTcpDst(tcpPort);
260 private class UdpSrcDecoder implements CriterionDecoder {
262 public Criterion decodeCriterion(ObjectNode json) {
263 TpPort udpPort = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.UDP_PORT),
264 CriterionCodec.UDP_PORT + MISSING_MEMBER_MESSAGE).asInt());
265 return Criteria.matchUdpSrc(udpPort);
269 private class UdpDstDecoder implements CriterionDecoder {
271 public Criterion decodeCriterion(ObjectNode json) {
272 TpPort udpPort = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.UDP_PORT),
273 CriterionCodec.UDP_PORT + MISSING_MEMBER_MESSAGE).asInt());
274 return Criteria.matchUdpDst(udpPort);
278 private class SctpSrcDecoder implements CriterionDecoder {
280 public Criterion decodeCriterion(ObjectNode json) {
281 TpPort sctpPort = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.SCTP_PORT),
282 CriterionCodec.SCTP_PORT + MISSING_MEMBER_MESSAGE).asInt());
283 return Criteria.matchSctpSrc(sctpPort);
287 private class SctpDstDecoder implements CriterionDecoder {
289 public Criterion decodeCriterion(ObjectNode json) {
290 TpPort sctpPort = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.SCTP_PORT),
291 CriterionCodec.SCTP_PORT + MISSING_MEMBER_MESSAGE).asInt());
292 return Criteria.matchSctpDst(sctpPort);
296 private class IcmpV4TypeDecoder implements CriterionDecoder {
298 public Criterion decodeCriterion(ObjectNode json) {
299 short type = (short) nullIsIllegal(json.get(CriterionCodec.ICMP_TYPE),
300 CriterionCodec.ICMP_TYPE + MISSING_MEMBER_MESSAGE).asInt();
301 return Criteria.matchIcmpType(type);
305 private class IcmpV4CodeDecoder implements CriterionDecoder {
307 public Criterion decodeCriterion(ObjectNode json) {
308 short code = (short) nullIsIllegal(json.get(CriterionCodec.ICMP_CODE),
309 CriterionCodec.ICMP_CODE + MISSING_MEMBER_MESSAGE).asInt();
310 return Criteria.matchIcmpCode(code);
314 private class IpV6FLabelDecoder implements CriterionDecoder {
316 public Criterion decodeCriterion(ObjectNode json) {
317 int flowLabel = nullIsIllegal(json.get(CriterionCodec.FLOW_LABEL),
318 CriterionCodec.FLOW_LABEL + MISSING_MEMBER_MESSAGE).asInt();
319 return Criteria.matchIPv6FlowLabel(flowLabel);
323 private class IcmpV6TypeDecoder implements CriterionDecoder {
325 public Criterion decodeCriterion(ObjectNode json) {
326 short type = (short) nullIsIllegal(json.get(CriterionCodec.ICMPV6_TYPE),
327 CriterionCodec.ICMPV6_TYPE + MISSING_MEMBER_MESSAGE).asInt();
328 return Criteria.matchIcmpv6Type(type);
332 private class IcmpV6CodeDecoder implements CriterionDecoder {
334 public Criterion decodeCriterion(ObjectNode json) {
335 short code = (short) nullIsIllegal(json.get(CriterionCodec.ICMPV6_CODE),
336 CriterionCodec.ICMPV6_CODE + MISSING_MEMBER_MESSAGE).asInt();
337 return Criteria.matchIcmpv6Code(code);
341 private class V6NDTargetDecoder implements CriterionDecoder {
343 public Criterion decodeCriterion(ObjectNode json) {
344 Ip6Address target = Ip6Address.valueOf(nullIsIllegal(json.get(CriterionCodec.TARGET_ADDRESS),
345 CriterionCodec.TARGET_ADDRESS + MISSING_MEMBER_MESSAGE).asText());
346 return Criteria.matchIPv6NDTargetAddress(target);
350 private class V6NDSllDecoder implements CriterionDecoder {
352 public Criterion decodeCriterion(ObjectNode json) {
353 MacAddress mac = MacAddress.valueOf(nullIsIllegal(json.get(CriterionCodec.MAC),
354 CriterionCodec.MAC + MISSING_MEMBER_MESSAGE).asText());
355 return Criteria.matchIPv6NDSourceLinkLayerAddress(mac);
359 private class V6NDTllDecoder implements CriterionDecoder {
361 public Criterion decodeCriterion(ObjectNode json) {
362 MacAddress mac = MacAddress.valueOf(nullIsIllegal(json.get(CriterionCodec.MAC),
363 CriterionCodec.MAC + MISSING_MEMBER_MESSAGE).asText());
364 return Criteria.matchIPv6NDTargetLinkLayerAddress(mac);
368 private class MplsLabelDecoder implements CriterionDecoder {
370 public Criterion decodeCriterion(ObjectNode json) {
371 int label = nullIsIllegal(json.get(CriterionCodec.LABEL),
372 CriterionCodec.LABEL + MISSING_MEMBER_MESSAGE).asInt();
373 return Criteria.matchMplsLabel(MplsLabel.mplsLabel(label));
377 private class IpV6ExthdrDecoder implements CriterionDecoder {
379 public Criterion decodeCriterion(ObjectNode json) {
380 int exthdrFlags = nullIsIllegal(json.get(CriterionCodec.EXT_HDR_FLAGS),
381 CriterionCodec.EXT_HDR_FLAGS + MISSING_MEMBER_MESSAGE).asInt();
382 return Criteria.matchIPv6ExthdrFlags(exthdrFlags);
386 private class OchSigIdDecoder implements CriterionDecoder {
388 public Criterion decodeCriterion(ObjectNode json) {
389 if (json.get(CriterionCodec.LAMBDA) != null) {
390 Lambda lambda = Lambda.indexedLambda(nullIsIllegal(json.get(CriterionCodec.LAMBDA),
391 CriterionCodec.LAMBDA + MISSING_MEMBER_MESSAGE).asInt());
392 return Criteria.matchLambda(lambda);
394 JsonNode ochSignalId = nullIsIllegal(json.get(CriterionCodec.OCH_SIGNAL_ID),
395 CriterionCodec.GRID_TYPE + MISSING_MEMBER_MESSAGE);
398 nullIsIllegal(ochSignalId.get(CriterionCodec.GRID_TYPE),
399 CriterionCodec.GRID_TYPE + MISSING_MEMBER_MESSAGE).asText());
400 ChannelSpacing channelSpacing =
401 ChannelSpacing.valueOf(
402 nullIsIllegal(ochSignalId.get(CriterionCodec.CHANNEL_SPACING),
403 CriterionCodec.CHANNEL_SPACING + MISSING_MEMBER_MESSAGE).asText());
404 int spacingMultiplier = nullIsIllegal(ochSignalId.get(CriterionCodec.SPACING_MULIPLIER),
405 CriterionCodec.SPACING_MULIPLIER + MISSING_MEMBER_MESSAGE).asInt();
406 int slotGranularity = nullIsIllegal(ochSignalId.get(CriterionCodec.SLOT_GRANULARITY),
407 CriterionCodec.SLOT_GRANULARITY + MISSING_MEMBER_MESSAGE).asInt();
408 return Criteria.matchLambda(
409 Lambda.ochSignal(gridType, channelSpacing,
410 spacingMultiplier, slotGranularity));
415 private class OchSigTypeDecoder implements CriterionDecoder {
417 public Criterion decodeCriterion(ObjectNode json) {
422 private class TunnelIdDecoder implements CriterionDecoder {
424 public Criterion decodeCriterion(ObjectNode json) {
425 long tunnelId = nullIsIllegal(json.get(CriterionCodec.TUNNEL_ID),
426 CriterionCodec.TUNNEL_ID + MISSING_MEMBER_MESSAGE).asLong();
427 return Criteria.matchTunnelId(tunnelId);
432 * Decodes the JSON into a criterion object.
434 * @return Criterion object
435 * @throws IllegalArgumentException if the JSON is invalid
437 public Criterion decode() {
438 String type = json.get(CriterionCodec.TYPE).asText();
440 CriterionDecoder decoder = decoderMap.get(type);
441 if (decoder != null) {
442 return decoder.decodeCriterion(json);
445 throw new IllegalArgumentException("Type " + type + " is unknown");