blob: 9516ed3a5af2f92a82c130024c4953799c37069f [file] [log] [blame]
Ray Milkeyd43fe452015-05-29 09:35:12 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
Ray Milkeyd43fe452015-05-29 09:35:12 -07003 *
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
Seyeon Jeong8d3cad22020-02-28 01:17:34 -080018import com.esotericsoftware.kryo.io.Input;
andread35f89c2015-11-23 10:02:07 -080019import com.fasterxml.jackson.databind.JsonNode;
20import com.fasterxml.jackson.databind.node.ObjectNode;
Ray Milkeyd43fe452015-05-29 09:35:12 -070021import org.onlab.packet.Ip6Address;
22import org.onlab.packet.IpPrefix;
23import org.onlab.packet.MacAddress;
24import org.onlab.packet.MplsLabel;
Hyunsun Mooncf732fb2015-08-22 21:04:23 -070025import org.onlab.packet.TpPort;
Ray Milkeyd43fe452015-05-29 09:35:12 -070026import org.onlab.packet.VlanId;
Yafit Hadar5796d972015-10-15 13:16:11 +030027import org.onlab.util.HexString;
Ray Milkeyd43fe452015-05-29 09:35:12 -070028import org.onosproject.net.ChannelSpacing;
29import org.onosproject.net.GridType;
30import org.onosproject.net.Lambda;
Yafit Hadar5796d972015-10-15 13:16:11 +030031import org.onosproject.net.OchSignalType;
32import org.onosproject.net.OduSignalId;
33import org.onosproject.net.OduSignalType;
Ray Milkeyd43fe452015-05-29 09:35:12 -070034import org.onosproject.net.PortNumber;
35import org.onosproject.net.flow.criteria.Criteria;
36import org.onosproject.net.flow.criteria.Criterion;
Seyeon Jeong8d3cad22020-02-28 01:17:34 -080037import org.onosproject.net.flow.criteria.ExtensionCriterion;
Frank Wang74ce2c12018-04-11 20:26:45 +080038import org.onosproject.net.flow.criteria.PiCriterion;
39import org.onosproject.net.pi.model.PiMatchFieldId;
40import org.onosproject.net.pi.model.PiMatchType;
Seyeon Jeong8d3cad22020-02-28 01:17:34 -080041import org.onosproject.store.serializers.KryoNamespaces;
42import org.slf4j.Logger;
Ray Milkeyd43fe452015-05-29 09:35:12 -070043
Seyeon Jeong8d3cad22020-02-28 01:17:34 -080044import java.io.ByteArrayInputStream;
45import java.io.IOException;
andread35f89c2015-11-23 10:02:07 -080046import java.util.HashMap;
47import java.util.Map;
48
49import static org.onlab.util.Tools.nullIsIllegal;
Seyeon Jeong8d3cad22020-02-28 01:17:34 -080050import static org.slf4j.LoggerFactory.getLogger;
Ray Milkeyd43fe452015-05-29 09:35:12 -070051
Ray Milkeyd43fe452015-05-29 09:35:12 -070052/**
53 * Decode portion of the criterion codec.
54 */
Ray Milkey6d7968e2015-07-06 14:30:02 -070055public final class DecodeCriterionCodecHelper {
Ray Milkeyd43fe452015-05-29 09:35:12 -070056
Seyeon Jeong8d3cad22020-02-28 01:17:34 -080057 private static final Logger log = getLogger(DecodeCriterionCodecHelper.class);
58
Ray Milkeyd43fe452015-05-29 09:35:12 -070059 private final ObjectNode json;
60
61 protected static final String MISSING_MEMBER_MESSAGE =
62 " member is required in Criterion";
63
64 private interface CriterionDecoder {
65 Criterion decodeCriterion(ObjectNode json);
66 }
67 private final Map<String, CriterionDecoder> decoderMap;
68
69 /**
70 * Creates a decode criterion codec object.
71 * Initializes the lookup map for criterion subclass decoders.
72 *
73 * @param json JSON object to decode
74 */
Ray Milkey6d7968e2015-07-06 14:30:02 -070075 public DecodeCriterionCodecHelper(ObjectNode json) {
Ray Milkeyd43fe452015-05-29 09:35:12 -070076 this.json = json;
77 decoderMap = new HashMap<>();
78
79 decoderMap.put(Criterion.Type.IN_PORT.name(), new InPortDecoder());
80 decoderMap.put(Criterion.Type.IN_PHY_PORT.name(), new InPhyPortDecoder());
81 decoderMap.put(Criterion.Type.METADATA.name(), new MetadataDecoder());
82 decoderMap.put(Criterion.Type.ETH_DST.name(), new EthDstDecoder());
Seyeon Jeong8f014142020-02-26 12:51:03 -080083 decoderMap.put(Criterion.Type.ETH_DST_MASKED.name(), new EthDstMaskedDecoder());
Ray Milkeyd43fe452015-05-29 09:35:12 -070084 decoderMap.put(Criterion.Type.ETH_SRC.name(), new EthSrcDecoder());
85 decoderMap.put(Criterion.Type.ETH_TYPE.name(), new EthTypeDecoder());
86 decoderMap.put(Criterion.Type.VLAN_VID.name(), new VlanVidDecoder());
87 decoderMap.put(Criterion.Type.VLAN_PCP.name(), new VlanPcpDecoder());
alshabibfa0dc662016-01-13 11:23:53 -080088 decoderMap.put(Criterion.Type.INNER_VLAN_VID.name(), new InnerVlanVidDecoder());
89 decoderMap.put(Criterion.Type.INNER_VLAN_PCP.name(), new InnerVlanPcpDecoder());
Ray Milkeyd43fe452015-05-29 09:35:12 -070090 decoderMap.put(Criterion.Type.IP_DSCP.name(), new IpDscpDecoder());
91 decoderMap.put(Criterion.Type.IP_ECN.name(), new IpEcnDecoder());
92 decoderMap.put(Criterion.Type.IP_PROTO.name(), new IpProtoDecoder());
93 decoderMap.put(Criterion.Type.IPV4_SRC.name(), new IpV4SrcDecoder());
94 decoderMap.put(Criterion.Type.IPV4_DST.name(), new IpV4DstDecoder());
95 decoderMap.put(Criterion.Type.TCP_SRC.name(), new TcpSrcDecoder());
Andreas Gilbert5e959612017-12-20 10:30:18 +010096 decoderMap.put(Criterion.Type.TCP_SRC_MASKED.name(), new TcpSrcMaskDecoder());
Ray Milkeyd43fe452015-05-29 09:35:12 -070097 decoderMap.put(Criterion.Type.TCP_DST.name(), new TcpDstDecoder());
Andreas Gilbert5e959612017-12-20 10:30:18 +010098 decoderMap.put(Criterion.Type.TCP_DST_MASKED.name(), new TcpDstMaskDecoder());
Ray Milkeyd43fe452015-05-29 09:35:12 -070099 decoderMap.put(Criterion.Type.UDP_SRC.name(), new UdpSrcDecoder());
Andreas Gilbert5e959612017-12-20 10:30:18 +0100100 decoderMap.put(Criterion.Type.UDP_SRC_MASKED.name(), new UdpSrcMaskDecoder());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700101 decoderMap.put(Criterion.Type.UDP_DST.name(), new UdpDstDecoder());
Andreas Gilbert5e959612017-12-20 10:30:18 +0100102 decoderMap.put(Criterion.Type.UDP_DST_MASKED.name(), new UdpDstMaskDecoder());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700103 decoderMap.put(Criterion.Type.SCTP_SRC.name(), new SctpSrcDecoder());
Andreas Gilbert5e959612017-12-20 10:30:18 +0100104 decoderMap.put(Criterion.Type.SCTP_SRC_MASKED.name(), new SctpSrcMaskDecoder());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700105 decoderMap.put(Criterion.Type.SCTP_DST.name(), new SctpDstDecoder());
Andreas Gilbert5e959612017-12-20 10:30:18 +0100106 decoderMap.put(Criterion.Type.SCTP_DST_MASKED.name(), new SctpDstMaskDecoder());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700107 decoderMap.put(Criterion.Type.ICMPV4_TYPE.name(), new IcmpV4TypeDecoder());
108 decoderMap.put(Criterion.Type.ICMPV4_CODE.name(), new IcmpV4CodeDecoder());
109 decoderMap.put(Criterion.Type.IPV6_SRC.name(), new IpV6SrcDecoder());
110 decoderMap.put(Criterion.Type.IPV6_DST.name(), new IpV6DstDecoder());
111 decoderMap.put(Criterion.Type.IPV6_FLABEL.name(), new IpV6FLabelDecoder());
112 decoderMap.put(Criterion.Type.ICMPV6_TYPE.name(), new IcmpV6TypeDecoder());
113 decoderMap.put(Criterion.Type.ICMPV6_CODE.name(), new IcmpV6CodeDecoder());
114 decoderMap.put(Criterion.Type.IPV6_ND_TARGET.name(), new V6NDTargetDecoder());
115 decoderMap.put(Criterion.Type.IPV6_ND_SLL.name(), new V6NDSllDecoder());
116 decoderMap.put(Criterion.Type.IPV6_ND_TLL.name(), new V6NDTllDecoder());
117 decoderMap.put(Criterion.Type.MPLS_LABEL.name(), new MplsLabelDecoder());
Jonathan Hartcc962d82016-08-09 16:52:22 -0700118 decoderMap.put(Criterion.Type.MPLS_BOS.name(), new MplsBosDecoder());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700119 decoderMap.put(Criterion.Type.IPV6_EXTHDR.name(), new IpV6ExthdrDecoder());
120 decoderMap.put(Criterion.Type.OCH_SIGID.name(), new OchSigIdDecoder());
121 decoderMap.put(Criterion.Type.OCH_SIGTYPE.name(), new OchSigTypeDecoder());
Hyunsun Moon7080a0d2015-08-14 19:18:48 -0700122 decoderMap.put(Criterion.Type.TUNNEL_ID.name(), new TunnelIdDecoder());
Yafit Hadar5796d972015-10-15 13:16:11 +0300123 decoderMap.put(Criterion.Type.ODU_SIGID.name(), new OduSigIdDecoder());
124 decoderMap.put(Criterion.Type.ODU_SIGTYPE.name(), new OduSigTypeDecoder());
Frank Wang74ce2c12018-04-11 20:26:45 +0800125 decoderMap.put(Criterion.Type.PROTOCOL_INDEPENDENT.name(), new PiDecoder());
Seyeon Jeong8d3cad22020-02-28 01:17:34 -0800126 decoderMap.put(Criterion.Type.EXTENSION.name(), new ExtensionDecoder());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700127 }
128
129 private class EthTypeDecoder implements CriterionDecoder {
130 @Override
131 public Criterion decodeCriterion(ObjectNode json) {
Ray Milkeyfe447c52016-02-24 14:17:54 -0800132 JsonNode ethTypeNode = nullIsIllegal(json.get(CriterionCodec.ETH_TYPE),
133 CriterionCodec.ETH_TYPE + MISSING_MEMBER_MESSAGE);
andread35f89c2015-11-23 10:02:07 -0800134 int ethType;
Ray Milkeyfe447c52016-02-24 14:17:54 -0800135 if (ethTypeNode.isInt()) {
136 ethType = ethTypeNode.asInt();
andread35f89c2015-11-23 10:02:07 -0800137 } else {
Ray Milkeyfe447c52016-02-24 14:17:54 -0800138 ethType = Integer.decode(ethTypeNode.textValue());
andread35f89c2015-11-23 10:02:07 -0800139 }
Ray Milkeyd43fe452015-05-29 09:35:12 -0700140 return Criteria.matchEthType(ethType);
141 }
142 }
Seyeon Jeong8d3cad22020-02-28 01:17:34 -0800143
Ray Milkeyd43fe452015-05-29 09:35:12 -0700144 private class EthDstDecoder implements CriterionDecoder {
145 @Override
146 public Criterion decodeCriterion(ObjectNode json) {
147 MacAddress mac = MacAddress.valueOf(nullIsIllegal(json.get(CriterionCodec.MAC),
148 CriterionCodec.MAC + MISSING_MEMBER_MESSAGE).asText());
149
150 return Criteria.matchEthDst(mac);
151 }
152 }
Seyeon Jeong8d3cad22020-02-28 01:17:34 -0800153
Seyeon Jeong8f014142020-02-26 12:51:03 -0800154 private class EthDstMaskedDecoder implements CriterionDecoder {
155 @Override
156 public Criterion decodeCriterion(ObjectNode json) {
157 MacAddress mac = MacAddress.valueOf(nullIsIllegal(json.get(CriterionCodec.MAC),
158 CriterionCodec.MAC + MISSING_MEMBER_MESSAGE).asText());
159 MacAddress macMask = MacAddress.valueOf(nullIsIllegal(json.get(CriterionCodec.MAC_MASK),
160 CriterionCodec.MAC + MISSING_MEMBER_MESSAGE).asText());
161 return Criteria.matchEthDstMasked(mac, macMask);
162 }
163 }
Seyeon Jeong8d3cad22020-02-28 01:17:34 -0800164
Ray Milkeyd43fe452015-05-29 09:35:12 -0700165 private class EthSrcDecoder implements CriterionDecoder {
166 @Override
167 public Criterion decodeCriterion(ObjectNode json) {
168 MacAddress mac = MacAddress.valueOf(nullIsIllegal(json.get(CriterionCodec.MAC),
169 CriterionCodec.MAC + MISSING_MEMBER_MESSAGE).asText());
170
171 return Criteria.matchEthSrc(mac);
172 }
173 }
174
175 private class InPortDecoder implements CriterionDecoder {
176 @Override
177 public Criterion decodeCriterion(ObjectNode json) {
178 PortNumber port = PortNumber.portNumber(nullIsIllegal(json.get(CriterionCodec.PORT),
alshabibfa0dc662016-01-13 11:23:53 -0800179 CriterionCodec.PORT +
180 MISSING_MEMBER_MESSAGE).asLong());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700181
182 return Criteria.matchInPort(port);
183 }
184 }
185
186 private class InPhyPortDecoder implements CriterionDecoder {
187 @Override
188 public Criterion decodeCriterion(ObjectNode json) {
189 PortNumber port = PortNumber.portNumber(nullIsIllegal(json.get(CriterionCodec.PORT),
alshabibfa0dc662016-01-13 11:23:53 -0800190 CriterionCodec.PORT +
191 MISSING_MEMBER_MESSAGE).asLong());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700192
193 return Criteria.matchInPhyPort(port);
194 }
195 }
196
197 private class MetadataDecoder implements CriterionDecoder {
198 @Override
199 public Criterion decodeCriterion(ObjectNode json) {
200 long metadata = nullIsIllegal(json.get(CriterionCodec.METADATA),
201 CriterionCodec.METADATA + MISSING_MEMBER_MESSAGE).asLong();
202
203 return Criteria.matchMetadata(metadata);
204 }
205 }
206
207 private class VlanVidDecoder implements CriterionDecoder {
208 @Override
209 public Criterion decodeCriterion(ObjectNode json) {
210 short vlanId = (short) nullIsIllegal(json.get(CriterionCodec.VLAN_ID),
211 CriterionCodec.VLAN_ID + MISSING_MEMBER_MESSAGE).asInt();
212
213 return Criteria.matchVlanId(VlanId.vlanId(vlanId));
214 }
215 }
216
217 private class VlanPcpDecoder implements CriterionDecoder {
218 @Override
219 public Criterion decodeCriterion(ObjectNode json) {
220 byte priority = (byte) nullIsIllegal(json.get(CriterionCodec.PRIORITY),
alshabibfa0dc662016-01-13 11:23:53 -0800221 CriterionCodec.PRIORITY + MISSING_MEMBER_MESSAGE).asInt();
Ray Milkeyd43fe452015-05-29 09:35:12 -0700222
223 return Criteria.matchVlanPcp(priority);
224 }
225 }
226
alshabibfa0dc662016-01-13 11:23:53 -0800227 private class InnerVlanVidDecoder implements CriterionDecoder {
228 @Override
229 public Criterion decodeCriterion(ObjectNode json) {
230 short vlanId = (short) nullIsIllegal(json.get(CriterionCodec.INNER_VLAN_ID),
231 CriterionCodec.INNER_VLAN_ID +
232 MISSING_MEMBER_MESSAGE).asInt();
233
234 return Criteria.matchInnerVlanId(VlanId.vlanId(vlanId));
235 }
236 }
237
238 private class InnerVlanPcpDecoder implements CriterionDecoder {
239 @Override
240 public Criterion decodeCriterion(ObjectNode json) {
241 byte priority = (byte) nullIsIllegal(json.get(CriterionCodec.INNER_PRIORITY),
242 CriterionCodec.INNER_PRIORITY +
243 MISSING_MEMBER_MESSAGE).asInt();
244
245 return Criteria.matchInnerVlanPcp(priority);
246 }
247 }
248
Ray Milkeyd43fe452015-05-29 09:35:12 -0700249 private class IpDscpDecoder implements CriterionDecoder {
250 @Override
251 public Criterion decodeCriterion(ObjectNode json) {
252 byte ipDscp = (byte) nullIsIllegal(json.get(CriterionCodec.IP_DSCP),
253 CriterionCodec.IP_DSCP + MISSING_MEMBER_MESSAGE).asInt();
254 return Criteria.matchIPDscp(ipDscp);
255 }
256 }
257
258 private class IpEcnDecoder implements CriterionDecoder {
259 @Override
260 public Criterion decodeCriterion(ObjectNode json) {
261 byte ipEcn = (byte) nullIsIllegal(json.get(CriterionCodec.IP_ECN),
262 CriterionCodec.IP_ECN + MISSING_MEMBER_MESSAGE).asInt();
263 return Criteria.matchIPEcn(ipEcn);
264 }
265 }
266
267 private class IpProtoDecoder implements CriterionDecoder {
268 @Override
269 public Criterion decodeCriterion(ObjectNode json) {
270 short proto = (short) nullIsIllegal(json.get(CriterionCodec.PROTOCOL),
271 CriterionCodec.PROTOCOL + MISSING_MEMBER_MESSAGE).asInt();
272 return Criteria.matchIPProtocol(proto);
273 }
274 }
275
276 private class IpV4SrcDecoder implements CriterionDecoder {
277 @Override
278 public Criterion decodeCriterion(ObjectNode json) {
279 String ip = nullIsIllegal(json.get(CriterionCodec.IP),
280 CriterionCodec.IP + MISSING_MEMBER_MESSAGE).asText();
281 return Criteria.matchIPSrc(IpPrefix.valueOf(ip));
282 }
283 }
284
285 private class IpV4DstDecoder implements CriterionDecoder {
286 @Override
287 public Criterion decodeCriterion(ObjectNode json) {
288 String ip = nullIsIllegal(json.get(CriterionCodec.IP),
289 CriterionCodec.IP + MISSING_MEMBER_MESSAGE).asText();
290 return Criteria.matchIPDst(IpPrefix.valueOf(ip));
291 }
292 }
293
294 private class IpV6SrcDecoder implements CriterionDecoder {
295 @Override
296 public Criterion decodeCriterion(ObjectNode json) {
297 String ip = nullIsIllegal(json.get(CriterionCodec.IP),
298 CriterionCodec.IP + MISSING_MEMBER_MESSAGE).asText();
299 return Criteria.matchIPv6Src(IpPrefix.valueOf(ip));
300 }
301 }
302
303 private class IpV6DstDecoder implements CriterionDecoder {
304 @Override
305 public Criterion decodeCriterion(ObjectNode json) {
306 String ip = nullIsIllegal(json.get(CriterionCodec.IP),
307 CriterionCodec.IP + MISSING_MEMBER_MESSAGE).asText();
308 return Criteria.matchIPv6Dst(IpPrefix.valueOf(ip));
309 }
310 }
311
312 private class TcpSrcDecoder implements CriterionDecoder {
313 @Override
314 public Criterion decodeCriterion(ObjectNode json) {
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700315 TpPort tcpPort = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.TCP_PORT),
316 CriterionCodec.TCP_PORT + MISSING_MEMBER_MESSAGE).asInt());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700317 return Criteria.matchTcpSrc(tcpPort);
318 }
319 }
320
Andreas Gilbert5e959612017-12-20 10:30:18 +0100321 private class TcpSrcMaskDecoder implements CriterionDecoder {
322 @Override
323 public Criterion decodeCriterion(ObjectNode json) {
324 TpPort tcpPort = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.TCP_PORT),
325 CriterionCodec.TCP_PORT + MISSING_MEMBER_MESSAGE).asInt());
326
327 TpPort tcpMask = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.TCP_MASK),
328 CriterionCodec.TCP_MASK + MISSING_MEMBER_MESSAGE).asInt());
329
330 return Criteria.matchTcpSrcMasked(tcpPort, tcpMask);
331 }
332 }
333
Ray Milkeyd43fe452015-05-29 09:35:12 -0700334 private class TcpDstDecoder implements CriterionDecoder {
335 @Override
336 public Criterion decodeCriterion(ObjectNode json) {
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700337 TpPort tcpPort = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.TCP_PORT),
338 CriterionCodec.TCP_PORT + MISSING_MEMBER_MESSAGE).asInt());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700339 return Criteria.matchTcpDst(tcpPort);
340 }
341 }
342
Andreas Gilbert5e959612017-12-20 10:30:18 +0100343 private class TcpDstMaskDecoder implements CriterionDecoder {
344 @Override
345 public Criterion decodeCriterion(ObjectNode json) {
346 TpPort tcpPort = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.TCP_PORT),
347 CriterionCodec.TCP_PORT + MISSING_MEMBER_MESSAGE).asInt());
348
349 TpPort tcpMask = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.TCP_MASK),
350 CriterionCodec.TCP_MASK + MISSING_MEMBER_MESSAGE).asInt());
351
352 return Criteria.matchTcpDstMasked(tcpPort, tcpMask);
353 }
354 }
355
Ray Milkeyd43fe452015-05-29 09:35:12 -0700356 private class UdpSrcDecoder implements CriterionDecoder {
357 @Override
358 public Criterion decodeCriterion(ObjectNode json) {
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700359 TpPort udpPort = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.UDP_PORT),
360 CriterionCodec.UDP_PORT + MISSING_MEMBER_MESSAGE).asInt());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700361 return Criteria.matchUdpSrc(udpPort);
362 }
363 }
364
Andreas Gilbert5e959612017-12-20 10:30:18 +0100365 private class UdpSrcMaskDecoder implements CriterionDecoder {
366 @Override
367 public Criterion decodeCriterion(ObjectNode json) {
368 TpPort udpPort = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.UDP_PORT),
369 CriterionCodec.UDP_PORT + MISSING_MEMBER_MESSAGE).asInt());
370
371 TpPort udpMask = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.UDP_MASK),
372 CriterionCodec.UDP_MASK + MISSING_MEMBER_MESSAGE).asInt());
373
374 return Criteria.matchUdpSrcMasked(udpPort, udpMask);
375 }
376 }
377
Ray Milkeyd43fe452015-05-29 09:35:12 -0700378 private class UdpDstDecoder implements CriterionDecoder {
379 @Override
380 public Criterion decodeCriterion(ObjectNode json) {
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700381 TpPort udpPort = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.UDP_PORT),
382 CriterionCodec.UDP_PORT + MISSING_MEMBER_MESSAGE).asInt());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700383 return Criteria.matchUdpDst(udpPort);
384 }
385 }
386
Andreas Gilbert5e959612017-12-20 10:30:18 +0100387 private class UdpDstMaskDecoder implements CriterionDecoder {
388 @Override
389 public Criterion decodeCriterion(ObjectNode json) {
390 TpPort udpPort = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.UDP_PORT),
391 CriterionCodec.UDP_PORT + MISSING_MEMBER_MESSAGE).asInt());
392
393 TpPort udpMask = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.UDP_MASK),
394 CriterionCodec.UDP_MASK + MISSING_MEMBER_MESSAGE).asInt());
395
396 return Criteria.matchUdpDstMasked(udpPort, udpMask);
397 }
398 }
399
Ray Milkeyd43fe452015-05-29 09:35:12 -0700400 private class SctpSrcDecoder implements CriterionDecoder {
401 @Override
402 public Criterion decodeCriterion(ObjectNode json) {
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700403 TpPort sctpPort = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.SCTP_PORT),
404 CriterionCodec.SCTP_PORT + MISSING_MEMBER_MESSAGE).asInt());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700405 return Criteria.matchSctpSrc(sctpPort);
406 }
407 }
408
Andreas Gilbert5e959612017-12-20 10:30:18 +0100409 private class SctpSrcMaskDecoder implements CriterionDecoder {
410 @Override
411 public Criterion decodeCriterion(ObjectNode json) {
412 TpPort sctpPort = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.SCTP_PORT),
413 CriterionCodec.SCTP_PORT + MISSING_MEMBER_MESSAGE).asInt());
414
415 TpPort sctpMask = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.SCTP_MASK),
416 CriterionCodec.SCTP_MASK + MISSING_MEMBER_MESSAGE).asInt());
417
418 return Criteria.matchSctpSrcMasked(sctpPort, sctpMask);
419 }
420 }
421
Ray Milkeyd43fe452015-05-29 09:35:12 -0700422 private class SctpDstDecoder implements CriterionDecoder {
423 @Override
424 public Criterion decodeCriterion(ObjectNode json) {
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700425 TpPort sctpPort = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.SCTP_PORT),
426 CriterionCodec.SCTP_PORT + MISSING_MEMBER_MESSAGE).asInt());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700427 return Criteria.matchSctpDst(sctpPort);
428 }
429 }
430
Andreas Gilbert5e959612017-12-20 10:30:18 +0100431 private class SctpDstMaskDecoder implements CriterionDecoder {
432 @Override
433 public Criterion decodeCriterion(ObjectNode json) {
434 TpPort sctpPort = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.SCTP_PORT),
435 CriterionCodec.SCTP_PORT + MISSING_MEMBER_MESSAGE).asInt());
436
437 TpPort sctpMask = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.SCTP_MASK),
438 CriterionCodec.SCTP_MASK + MISSING_MEMBER_MESSAGE).asInt());
439
440 return Criteria.matchSctpDstMasked(sctpPort, sctpMask);
441 }
442 }
443
Ray Milkeyd43fe452015-05-29 09:35:12 -0700444 private class IcmpV4TypeDecoder implements CriterionDecoder {
445 @Override
446 public Criterion decodeCriterion(ObjectNode json) {
447 short type = (short) nullIsIllegal(json.get(CriterionCodec.ICMP_TYPE),
448 CriterionCodec.ICMP_TYPE + MISSING_MEMBER_MESSAGE).asInt();
449 return Criteria.matchIcmpType(type);
450 }
451 }
452
453 private class IcmpV4CodeDecoder implements CriterionDecoder {
454 @Override
455 public Criterion decodeCriterion(ObjectNode json) {
456 short code = (short) nullIsIllegal(json.get(CriterionCodec.ICMP_CODE),
457 CriterionCodec.ICMP_CODE + MISSING_MEMBER_MESSAGE).asInt();
458 return Criteria.matchIcmpCode(code);
459 }
460 }
461
462 private class IpV6FLabelDecoder implements CriterionDecoder {
463 @Override
464 public Criterion decodeCriterion(ObjectNode json) {
465 int flowLabel = nullIsIllegal(json.get(CriterionCodec.FLOW_LABEL),
466 CriterionCodec.FLOW_LABEL + MISSING_MEMBER_MESSAGE).asInt();
467 return Criteria.matchIPv6FlowLabel(flowLabel);
468 }
469 }
470
471 private class IcmpV6TypeDecoder implements CriterionDecoder {
472 @Override
473 public Criterion decodeCriterion(ObjectNode json) {
474 short type = (short) nullIsIllegal(json.get(CriterionCodec.ICMPV6_TYPE),
475 CriterionCodec.ICMPV6_TYPE + MISSING_MEMBER_MESSAGE).asInt();
476 return Criteria.matchIcmpv6Type(type);
477 }
478 }
479
480 private class IcmpV6CodeDecoder implements CriterionDecoder {
481 @Override
482 public Criterion decodeCriterion(ObjectNode json) {
483 short code = (short) nullIsIllegal(json.get(CriterionCodec.ICMPV6_CODE),
484 CriterionCodec.ICMPV6_CODE + MISSING_MEMBER_MESSAGE).asInt();
485 return Criteria.matchIcmpv6Code(code);
486 }
487 }
488
489 private class V6NDTargetDecoder implements CriterionDecoder {
490 @Override
491 public Criterion decodeCriterion(ObjectNode json) {
492 Ip6Address target = Ip6Address.valueOf(nullIsIllegal(json.get(CriterionCodec.TARGET_ADDRESS),
493 CriterionCodec.TARGET_ADDRESS + MISSING_MEMBER_MESSAGE).asText());
494 return Criteria.matchIPv6NDTargetAddress(target);
495 }
496 }
497
498 private class V6NDSllDecoder implements CriterionDecoder {
499 @Override
500 public Criterion decodeCriterion(ObjectNode json) {
501 MacAddress mac = MacAddress.valueOf(nullIsIllegal(json.get(CriterionCodec.MAC),
502 CriterionCodec.MAC + MISSING_MEMBER_MESSAGE).asText());
503 return Criteria.matchIPv6NDSourceLinkLayerAddress(mac);
504 }
505 }
506
507 private class V6NDTllDecoder implements CriterionDecoder {
508 @Override
509 public Criterion decodeCriterion(ObjectNode json) {
510 MacAddress mac = MacAddress.valueOf(nullIsIllegal(json.get(CriterionCodec.MAC),
511 CriterionCodec.MAC + MISSING_MEMBER_MESSAGE).asText());
512 return Criteria.matchIPv6NDTargetLinkLayerAddress(mac);
513 }
514 }
515
516 private class MplsLabelDecoder implements CriterionDecoder {
517 @Override
518 public Criterion decodeCriterion(ObjectNode json) {
519 int label = nullIsIllegal(json.get(CriterionCodec.LABEL),
520 CriterionCodec.LABEL + MISSING_MEMBER_MESSAGE).asInt();
521 return Criteria.matchMplsLabel(MplsLabel.mplsLabel(label));
522 }
523 }
524
Jonathan Hartcc962d82016-08-09 16:52:22 -0700525 private class MplsBosDecoder implements CriterionDecoder {
526 @Override
527 public Criterion decodeCriterion(ObjectNode json) {
528 boolean bos = nullIsIllegal(json.get(CriterionCodec.BOS),
529 CriterionCodec.BOS + MISSING_MEMBER_MESSAGE).asBoolean();
530 return Criteria.matchMplsBos(bos);
531 }
532 }
533
Ray Milkeyd43fe452015-05-29 09:35:12 -0700534 private class IpV6ExthdrDecoder implements CriterionDecoder {
535 @Override
536 public Criterion decodeCriterion(ObjectNode json) {
537 int exthdrFlags = nullIsIllegal(json.get(CriterionCodec.EXT_HDR_FLAGS),
538 CriterionCodec.EXT_HDR_FLAGS + MISSING_MEMBER_MESSAGE).asInt();
539 return Criteria.matchIPv6ExthdrFlags(exthdrFlags);
540 }
541 }
542
543 private class OchSigIdDecoder implements CriterionDecoder {
544 @Override
545 public Criterion decodeCriterion(ObjectNode json) {
Sho SHIMIZUcc137a92016-03-11 15:10:54 -0800546 JsonNode ochSignalId = nullIsIllegal(json.get(CriterionCodec.OCH_SIGNAL_ID),
547 CriterionCodec.GRID_TYPE + MISSING_MEMBER_MESSAGE);
548 GridType gridType =
549 GridType.valueOf(
550 nullIsIllegal(ochSignalId.get(CriterionCodec.GRID_TYPE),
551 CriterionCodec.GRID_TYPE + MISSING_MEMBER_MESSAGE).asText());
552 ChannelSpacing channelSpacing =
553 ChannelSpacing.valueOf(
554 nullIsIllegal(ochSignalId.get(CriterionCodec.CHANNEL_SPACING),
555 CriterionCodec.CHANNEL_SPACING + MISSING_MEMBER_MESSAGE).asText());
556 int spacingMultiplier = nullIsIllegal(ochSignalId.get(CriterionCodec.SPACING_MULIPLIER),
557 CriterionCodec.SPACING_MULIPLIER + MISSING_MEMBER_MESSAGE).asInt();
558 int slotGranularity = nullIsIllegal(ochSignalId.get(CriterionCodec.SLOT_GRANULARITY),
559 CriterionCodec.SLOT_GRANULARITY + MISSING_MEMBER_MESSAGE).asInt();
560 return Criteria.matchLambda(
561 Lambda.ochSignal(gridType, channelSpacing,
562 spacingMultiplier, slotGranularity));
Ray Milkeyd43fe452015-05-29 09:35:12 -0700563 }
564 }
565
566 private class OchSigTypeDecoder implements CriterionDecoder {
567 @Override
568 public Criterion decodeCriterion(ObjectNode json) {
Yafit Hadar5796d972015-10-15 13:16:11 +0300569 OchSignalType ochSignalType = OchSignalType.valueOf(nullIsIllegal(json.get(CriterionCodec.OCH_SIGNAL_TYPE),
570 CriterionCodec.OCH_SIGNAL_TYPE + MISSING_MEMBER_MESSAGE).asText());
571 return Criteria.matchOchSignalType(ochSignalType);
Ray Milkeyd43fe452015-05-29 09:35:12 -0700572 }
573 }
574
Hyunsun Moon7080a0d2015-08-14 19:18:48 -0700575 private class TunnelIdDecoder implements CriterionDecoder {
576 @Override
577 public Criterion decodeCriterion(ObjectNode json) {
578 long tunnelId = nullIsIllegal(json.get(CriterionCodec.TUNNEL_ID),
579 CriterionCodec.TUNNEL_ID + MISSING_MEMBER_MESSAGE).asLong();
580 return Criteria.matchTunnelId(tunnelId);
581 }
582 }
583
Yafit Hadar5796d972015-10-15 13:16:11 +0300584 private class OduSigIdDecoder implements CriterionDecoder {
585 @Override
586 public Criterion decodeCriterion(ObjectNode json) {
587 JsonNode oduSignalId = nullIsIllegal(json.get(CriterionCodec.ODU_SIGNAL_ID),
588 CriterionCodec.TRIBUTARY_PORT_NUMBER + MISSING_MEMBER_MESSAGE);
589
590 int tributaryPortNumber = nullIsIllegal(oduSignalId.get(CriterionCodec.TRIBUTARY_PORT_NUMBER),
591 CriterionCodec.TRIBUTARY_PORT_NUMBER + MISSING_MEMBER_MESSAGE).asInt();
592 int tributarySlotLen = nullIsIllegal(oduSignalId.get(CriterionCodec.TRIBUTARY_SLOT_LEN),
593 CriterionCodec.TRIBUTARY_SLOT_LEN + MISSING_MEMBER_MESSAGE).asInt();
594 byte[] tributarySlotBitmap = HexString.fromHexString(
595 nullIsIllegal(oduSignalId.get(CriterionCodec.TRIBUTARY_SLOT_BITMAP),
596 CriterionCodec.TRIBUTARY_SLOT_BITMAP + MISSING_MEMBER_MESSAGE).asText());
597
598 return Criteria.matchOduSignalId(
599 OduSignalId.oduSignalId(tributaryPortNumber, tributarySlotLen, tributarySlotBitmap));
600 }
601 }
602
603 private class OduSigTypeDecoder implements CriterionDecoder {
604 @Override
605 public Criterion decodeCriterion(ObjectNode json) {
606 OduSignalType oduSignalType = OduSignalType.valueOf(nullIsIllegal(json.get(CriterionCodec.ODU_SIGNAL_TYPE),
607 CriterionCodec.ODU_SIGNAL_TYPE + MISSING_MEMBER_MESSAGE).asText());
608 return Criteria.matchOduSignalType(oduSignalType);
609 }
610 }
611
Frank Wang74ce2c12018-04-11 20:26:45 +0800612 private class PiDecoder implements CriterionDecoder {
613 @Override
614 public Criterion decodeCriterion(ObjectNode json) {
615 PiCriterion.Builder builder = PiCriterion.builder();
616 JsonNode matchesNode = nullIsIllegal(json.get(CriterionCodec.PI_MATCHES),
617 CriterionCodec.PI_MATCHES + MISSING_MEMBER_MESSAGE);
618 if (matchesNode.isArray()) {
619 for (JsonNode node : matchesNode) {
620 String type = nullIsIllegal(node.get(CriterionCodec.PI_MATCH_TYPE),
621 CriterionCodec.PI_MATCH_TYPE + MISSING_MEMBER_MESSAGE).asText();
622 switch (PiMatchType.valueOf(type.toUpperCase())) {
623 case EXACT:
624 builder.matchExact(
625 PiMatchFieldId.of(
626 nullIsIllegal(node.get(CriterionCodec.PI_MATCH_FIELD_ID),
627 CriterionCodec.PI_MATCH_FIELD_ID +
628 MISSING_MEMBER_MESSAGE).asText()),
629 HexString.fromHexString(nullIsIllegal(node.get(CriterionCodec.PI_MATCH_VALUE),
630 CriterionCodec.PI_MATCH_VALUE +
631 MISSING_MEMBER_MESSAGE).asText(), null));
632 break;
633 case LPM:
634 builder.matchLpm(
635 PiMatchFieldId.of(
636 nullIsIllegal(node.get(CriterionCodec.PI_MATCH_FIELD_ID),
637 CriterionCodec.PI_MATCH_FIELD_ID +
638 MISSING_MEMBER_MESSAGE).asText()),
639 HexString.fromHexString(nullIsIllegal(node.get(CriterionCodec.PI_MATCH_VALUE),
640 CriterionCodec.PI_MATCH_VALUE +
641 MISSING_MEMBER_MESSAGE).asText(), null),
642 nullIsIllegal(node.get(CriterionCodec.PI_MATCH_PREFIX),
643 CriterionCodec.PI_MATCH_PREFIX +
644 MISSING_MEMBER_MESSAGE).asInt());
645 break;
646 case TERNARY:
647 builder.matchTernary(
648 PiMatchFieldId.of(
649 nullIsIllegal(node.get(CriterionCodec.PI_MATCH_FIELD_ID),
650 CriterionCodec.PI_MATCH_FIELD_ID +
651 MISSING_MEMBER_MESSAGE).asText()),
652 HexString.fromHexString(nullIsIllegal(node.get(CriterionCodec.PI_MATCH_VALUE),
653 CriterionCodec.PI_MATCH_VALUE +
654 MISSING_MEMBER_MESSAGE).asText(), null),
655 HexString.fromHexString(nullIsIllegal(node.get(CriterionCodec.PI_MATCH_MASK),
656 CriterionCodec.PI_MATCH_MASK +
657 MISSING_MEMBER_MESSAGE).asText(), null));
658 break;
659 case RANGE:
660 builder.matchRange(
661 PiMatchFieldId.of(
662 nullIsIllegal(node.get(CriterionCodec.PI_MATCH_FIELD_ID),
663 CriterionCodec.PI_MATCH_FIELD_ID +
664 MISSING_MEMBER_MESSAGE).asText()),
665 HexString.fromHexString(nullIsIllegal(node.get(CriterionCodec.PI_MATCH_LOW_VALUE),
666 CriterionCodec.PI_MATCH_LOW_VALUE +
667 MISSING_MEMBER_MESSAGE).asText(), null),
668 HexString.fromHexString(nullIsIllegal(node.get(CriterionCodec.PI_MATCH_HIGH_VALUE),
669 CriterionCodec.PI_MATCH_HIGH_VALUE +
670 MISSING_MEMBER_MESSAGE).asText(), null)
671 );
672 break;
Frank Wang74ce2c12018-04-11 20:26:45 +0800673 default:
674 throw new IllegalArgumentException("Type " + type + " is unsupported");
675 }
676 }
677 } else {
678 throw new IllegalArgumentException("Protocol-independent matches must be in an array.");
679 }
680
681 return builder.build();
682 }
683 }
684
Seyeon Jeong8d3cad22020-02-28 01:17:34 -0800685 private class ExtensionDecoder implements CriterionDecoder {
686 @Override
687 public Criterion decodeCriterion(ObjectNode json) {
688 try {
689 byte[] buffer = nullIsIllegal(json.get(CriterionCodec.EXTENSION),
690 CriterionCodec.EXTENSION + MISSING_MEMBER_MESSAGE).binaryValue();
691 Input input = new Input(new ByteArrayInputStream(buffer));
692 ExtensionCriterion extensionCriterion =
693 KryoNamespaces.API.borrow().readObject(input, ExtensionCriterion.class);
694 input.close();
695 return extensionCriterion;
696 } catch (IOException e) {
697 log.warn("Cannot convert the {} field into byte array", CriterionCodec.EXTENSION);
698 return null;
699 }
700 }
701 }
702
Ray Milkeyd43fe452015-05-29 09:35:12 -0700703 /**
704 * Decodes the JSON into a criterion object.
705 *
706 * @return Criterion object
707 * @throws IllegalArgumentException if the JSON is invalid
708 */
709 public Criterion decode() {
Ray Milkey52075062016-02-03 17:36:48 -0800710 String type =
711 nullIsIllegal(json.get(CriterionCodec.TYPE), "Type not specified")
712 .asText();
Ray Milkeyd43fe452015-05-29 09:35:12 -0700713
714 CriterionDecoder decoder = decoderMap.get(type);
715 if (decoder != null) {
716 return decoder.decodeCriterion(json);
717 }
718
719 throw new IllegalArgumentException("Type " + type + " is unknown");
720 }
721
722
723}