blob: cbd1df3a98d7c2988c1cabf8614eae2c34fce950 [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());
David Glantz6210c4c2021-09-21 15:39:19 -050085 decoderMap.put(Criterion.Type.ETH_SRC_MASKED.name(), new EthSrcMaskedDecoder());
Ray Milkeyd43fe452015-05-29 09:35:12 -070086 decoderMap.put(Criterion.Type.ETH_TYPE.name(), new EthTypeDecoder());
87 decoderMap.put(Criterion.Type.VLAN_VID.name(), new VlanVidDecoder());
88 decoderMap.put(Criterion.Type.VLAN_PCP.name(), new VlanPcpDecoder());
alshabibfa0dc662016-01-13 11:23:53 -080089 decoderMap.put(Criterion.Type.INNER_VLAN_VID.name(), new InnerVlanVidDecoder());
90 decoderMap.put(Criterion.Type.INNER_VLAN_PCP.name(), new InnerVlanPcpDecoder());
Ray Milkeyd43fe452015-05-29 09:35:12 -070091 decoderMap.put(Criterion.Type.IP_DSCP.name(), new IpDscpDecoder());
92 decoderMap.put(Criterion.Type.IP_ECN.name(), new IpEcnDecoder());
93 decoderMap.put(Criterion.Type.IP_PROTO.name(), new IpProtoDecoder());
94 decoderMap.put(Criterion.Type.IPV4_SRC.name(), new IpV4SrcDecoder());
95 decoderMap.put(Criterion.Type.IPV4_DST.name(), new IpV4DstDecoder());
96 decoderMap.put(Criterion.Type.TCP_SRC.name(), new TcpSrcDecoder());
Andreas Gilbert5e959612017-12-20 10:30:18 +010097 decoderMap.put(Criterion.Type.TCP_SRC_MASKED.name(), new TcpSrcMaskDecoder());
Ray Milkeyd43fe452015-05-29 09:35:12 -070098 decoderMap.put(Criterion.Type.TCP_DST.name(), new TcpDstDecoder());
Andreas Gilbert5e959612017-12-20 10:30:18 +010099 decoderMap.put(Criterion.Type.TCP_DST_MASKED.name(), new TcpDstMaskDecoder());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700100 decoderMap.put(Criterion.Type.UDP_SRC.name(), new UdpSrcDecoder());
Andreas Gilbert5e959612017-12-20 10:30:18 +0100101 decoderMap.put(Criterion.Type.UDP_SRC_MASKED.name(), new UdpSrcMaskDecoder());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700102 decoderMap.put(Criterion.Type.UDP_DST.name(), new UdpDstDecoder());
Andreas Gilbert5e959612017-12-20 10:30:18 +0100103 decoderMap.put(Criterion.Type.UDP_DST_MASKED.name(), new UdpDstMaskDecoder());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700104 decoderMap.put(Criterion.Type.SCTP_SRC.name(), new SctpSrcDecoder());
Andreas Gilbert5e959612017-12-20 10:30:18 +0100105 decoderMap.put(Criterion.Type.SCTP_SRC_MASKED.name(), new SctpSrcMaskDecoder());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700106 decoderMap.put(Criterion.Type.SCTP_DST.name(), new SctpDstDecoder());
Andreas Gilbert5e959612017-12-20 10:30:18 +0100107 decoderMap.put(Criterion.Type.SCTP_DST_MASKED.name(), new SctpDstMaskDecoder());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700108 decoderMap.put(Criterion.Type.ICMPV4_TYPE.name(), new IcmpV4TypeDecoder());
109 decoderMap.put(Criterion.Type.ICMPV4_CODE.name(), new IcmpV4CodeDecoder());
110 decoderMap.put(Criterion.Type.IPV6_SRC.name(), new IpV6SrcDecoder());
111 decoderMap.put(Criterion.Type.IPV6_DST.name(), new IpV6DstDecoder());
112 decoderMap.put(Criterion.Type.IPV6_FLABEL.name(), new IpV6FLabelDecoder());
113 decoderMap.put(Criterion.Type.ICMPV6_TYPE.name(), new IcmpV6TypeDecoder());
114 decoderMap.put(Criterion.Type.ICMPV6_CODE.name(), new IcmpV6CodeDecoder());
115 decoderMap.put(Criterion.Type.IPV6_ND_TARGET.name(), new V6NDTargetDecoder());
116 decoderMap.put(Criterion.Type.IPV6_ND_SLL.name(), new V6NDSllDecoder());
117 decoderMap.put(Criterion.Type.IPV6_ND_TLL.name(), new V6NDTllDecoder());
118 decoderMap.put(Criterion.Type.MPLS_LABEL.name(), new MplsLabelDecoder());
Jonathan Hartcc962d82016-08-09 16:52:22 -0700119 decoderMap.put(Criterion.Type.MPLS_BOS.name(), new MplsBosDecoder());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700120 decoderMap.put(Criterion.Type.IPV6_EXTHDR.name(), new IpV6ExthdrDecoder());
121 decoderMap.put(Criterion.Type.OCH_SIGID.name(), new OchSigIdDecoder());
122 decoderMap.put(Criterion.Type.OCH_SIGTYPE.name(), new OchSigTypeDecoder());
Hyunsun Moon7080a0d2015-08-14 19:18:48 -0700123 decoderMap.put(Criterion.Type.TUNNEL_ID.name(), new TunnelIdDecoder());
Yafit Hadar5796d972015-10-15 13:16:11 +0300124 decoderMap.put(Criterion.Type.ODU_SIGID.name(), new OduSigIdDecoder());
125 decoderMap.put(Criterion.Type.ODU_SIGTYPE.name(), new OduSigTypeDecoder());
Frank Wang74ce2c12018-04-11 20:26:45 +0800126 decoderMap.put(Criterion.Type.PROTOCOL_INDEPENDENT.name(), new PiDecoder());
Seyeon Jeong8d3cad22020-02-28 01:17:34 -0800127 decoderMap.put(Criterion.Type.EXTENSION.name(), new ExtensionDecoder());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700128 }
129
130 private class EthTypeDecoder implements CriterionDecoder {
131 @Override
132 public Criterion decodeCriterion(ObjectNode json) {
Ray Milkeyfe447c52016-02-24 14:17:54 -0800133 JsonNode ethTypeNode = nullIsIllegal(json.get(CriterionCodec.ETH_TYPE),
134 CriterionCodec.ETH_TYPE + MISSING_MEMBER_MESSAGE);
andread35f89c2015-11-23 10:02:07 -0800135 int ethType;
Ray Milkeyfe447c52016-02-24 14:17:54 -0800136 if (ethTypeNode.isInt()) {
137 ethType = ethTypeNode.asInt();
andread35f89c2015-11-23 10:02:07 -0800138 } else {
Ray Milkeyfe447c52016-02-24 14:17:54 -0800139 ethType = Integer.decode(ethTypeNode.textValue());
andread35f89c2015-11-23 10:02:07 -0800140 }
Ray Milkeyd43fe452015-05-29 09:35:12 -0700141 return Criteria.matchEthType(ethType);
142 }
143 }
Seyeon Jeong8d3cad22020-02-28 01:17:34 -0800144
Ray Milkeyd43fe452015-05-29 09:35:12 -0700145 private class EthDstDecoder implements CriterionDecoder {
146 @Override
147 public Criterion decodeCriterion(ObjectNode json) {
148 MacAddress mac = MacAddress.valueOf(nullIsIllegal(json.get(CriterionCodec.MAC),
149 CriterionCodec.MAC + MISSING_MEMBER_MESSAGE).asText());
150
151 return Criteria.matchEthDst(mac);
152 }
153 }
Seyeon Jeong8d3cad22020-02-28 01:17:34 -0800154
Seyeon Jeong8f014142020-02-26 12:51:03 -0800155 private class EthDstMaskedDecoder implements CriterionDecoder {
156 @Override
157 public Criterion decodeCriterion(ObjectNode json) {
158 MacAddress mac = MacAddress.valueOf(nullIsIllegal(json.get(CriterionCodec.MAC),
David Glantz6210c4c2021-09-21 15:39:19 -0500159 CriterionCodec.MAC + MISSING_MEMBER_MESSAGE).asText());
Seyeon Jeong8f014142020-02-26 12:51:03 -0800160 MacAddress macMask = MacAddress.valueOf(nullIsIllegal(json.get(CriterionCodec.MAC_MASK),
David Glantz6210c4c2021-09-21 15:39:19 -0500161 CriterionCodec.MAC_MASK + MISSING_MEMBER_MESSAGE).asText());
Seyeon Jeong8f014142020-02-26 12:51:03 -0800162 return Criteria.matchEthDstMasked(mac, macMask);
163 }
164 }
Seyeon Jeong8d3cad22020-02-28 01:17:34 -0800165
Ray Milkeyd43fe452015-05-29 09:35:12 -0700166 private class EthSrcDecoder implements CriterionDecoder {
167 @Override
168 public Criterion decodeCriterion(ObjectNode json) {
169 MacAddress mac = MacAddress.valueOf(nullIsIllegal(json.get(CriterionCodec.MAC),
170 CriterionCodec.MAC + MISSING_MEMBER_MESSAGE).asText());
171
172 return Criteria.matchEthSrc(mac);
173 }
174 }
175
David Glantz6210c4c2021-09-21 15:39:19 -0500176 private class EthSrcMaskedDecoder implements CriterionDecoder {
177 @Override
178 public Criterion decodeCriterion(ObjectNode json) {
179 MacAddress mac = MacAddress.valueOf(nullIsIllegal(json.get(CriterionCodec.MAC),
180 CriterionCodec.MAC + MISSING_MEMBER_MESSAGE).asText());
181 MacAddress macMask = MacAddress.valueOf(nullIsIllegal(json.get(CriterionCodec.MAC_MASK),
182 CriterionCodec.MAC_MASK + MISSING_MEMBER_MESSAGE).asText());
183 return Criteria.matchEthSrcMasked(mac, macMask);
184 }
185 }
186
Ray Milkeyd43fe452015-05-29 09:35:12 -0700187 private class InPortDecoder implements CriterionDecoder {
188 @Override
189 public Criterion decodeCriterion(ObjectNode json) {
190 PortNumber port = PortNumber.portNumber(nullIsIllegal(json.get(CriterionCodec.PORT),
alshabibfa0dc662016-01-13 11:23:53 -0800191 CriterionCodec.PORT +
192 MISSING_MEMBER_MESSAGE).asLong());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700193
194 return Criteria.matchInPort(port);
195 }
196 }
197
198 private class InPhyPortDecoder implements CriterionDecoder {
199 @Override
200 public Criterion decodeCriterion(ObjectNode json) {
201 PortNumber port = PortNumber.portNumber(nullIsIllegal(json.get(CriterionCodec.PORT),
alshabibfa0dc662016-01-13 11:23:53 -0800202 CriterionCodec.PORT +
203 MISSING_MEMBER_MESSAGE).asLong());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700204
205 return Criteria.matchInPhyPort(port);
206 }
207 }
208
209 private class MetadataDecoder implements CriterionDecoder {
210 @Override
211 public Criterion decodeCriterion(ObjectNode json) {
212 long metadata = nullIsIllegal(json.get(CriterionCodec.METADATA),
213 CriterionCodec.METADATA + MISSING_MEMBER_MESSAGE).asLong();
214
215 return Criteria.matchMetadata(metadata);
216 }
217 }
218
219 private class VlanVidDecoder implements CriterionDecoder {
220 @Override
221 public Criterion decodeCriterion(ObjectNode json) {
222 short vlanId = (short) nullIsIllegal(json.get(CriterionCodec.VLAN_ID),
223 CriterionCodec.VLAN_ID + MISSING_MEMBER_MESSAGE).asInt();
224
225 return Criteria.matchVlanId(VlanId.vlanId(vlanId));
226 }
227 }
228
229 private class VlanPcpDecoder implements CriterionDecoder {
230 @Override
231 public Criterion decodeCriterion(ObjectNode json) {
232 byte priority = (byte) nullIsIllegal(json.get(CriterionCodec.PRIORITY),
alshabibfa0dc662016-01-13 11:23:53 -0800233 CriterionCodec.PRIORITY + MISSING_MEMBER_MESSAGE).asInt();
Ray Milkeyd43fe452015-05-29 09:35:12 -0700234
235 return Criteria.matchVlanPcp(priority);
236 }
237 }
238
alshabibfa0dc662016-01-13 11:23:53 -0800239 private class InnerVlanVidDecoder implements CriterionDecoder {
240 @Override
241 public Criterion decodeCriterion(ObjectNode json) {
242 short vlanId = (short) nullIsIllegal(json.get(CriterionCodec.INNER_VLAN_ID),
243 CriterionCodec.INNER_VLAN_ID +
244 MISSING_MEMBER_MESSAGE).asInt();
245
246 return Criteria.matchInnerVlanId(VlanId.vlanId(vlanId));
247 }
248 }
249
250 private class InnerVlanPcpDecoder implements CriterionDecoder {
251 @Override
252 public Criterion decodeCriterion(ObjectNode json) {
253 byte priority = (byte) nullIsIllegal(json.get(CriterionCodec.INNER_PRIORITY),
254 CriterionCodec.INNER_PRIORITY +
255 MISSING_MEMBER_MESSAGE).asInt();
256
257 return Criteria.matchInnerVlanPcp(priority);
258 }
259 }
260
Ray Milkeyd43fe452015-05-29 09:35:12 -0700261 private class IpDscpDecoder implements CriterionDecoder {
262 @Override
263 public Criterion decodeCriterion(ObjectNode json) {
264 byte ipDscp = (byte) nullIsIllegal(json.get(CriterionCodec.IP_DSCP),
265 CriterionCodec.IP_DSCP + MISSING_MEMBER_MESSAGE).asInt();
266 return Criteria.matchIPDscp(ipDscp);
267 }
268 }
269
270 private class IpEcnDecoder implements CriterionDecoder {
271 @Override
272 public Criterion decodeCriterion(ObjectNode json) {
273 byte ipEcn = (byte) nullIsIllegal(json.get(CriterionCodec.IP_ECN),
274 CriterionCodec.IP_ECN + MISSING_MEMBER_MESSAGE).asInt();
275 return Criteria.matchIPEcn(ipEcn);
276 }
277 }
278
279 private class IpProtoDecoder implements CriterionDecoder {
280 @Override
281 public Criterion decodeCriterion(ObjectNode json) {
282 short proto = (short) nullIsIllegal(json.get(CriterionCodec.PROTOCOL),
283 CriterionCodec.PROTOCOL + MISSING_MEMBER_MESSAGE).asInt();
284 return Criteria.matchIPProtocol(proto);
285 }
286 }
287
288 private class IpV4SrcDecoder implements CriterionDecoder {
289 @Override
290 public Criterion decodeCriterion(ObjectNode json) {
291 String ip = nullIsIllegal(json.get(CriterionCodec.IP),
292 CriterionCodec.IP + MISSING_MEMBER_MESSAGE).asText();
293 return Criteria.matchIPSrc(IpPrefix.valueOf(ip));
294 }
295 }
296
297 private class IpV4DstDecoder implements CriterionDecoder {
298 @Override
299 public Criterion decodeCriterion(ObjectNode json) {
300 String ip = nullIsIllegal(json.get(CriterionCodec.IP),
301 CriterionCodec.IP + MISSING_MEMBER_MESSAGE).asText();
302 return Criteria.matchIPDst(IpPrefix.valueOf(ip));
303 }
304 }
305
306 private class IpV6SrcDecoder implements CriterionDecoder {
307 @Override
308 public Criterion decodeCriterion(ObjectNode json) {
309 String ip = nullIsIllegal(json.get(CriterionCodec.IP),
310 CriterionCodec.IP + MISSING_MEMBER_MESSAGE).asText();
311 return Criteria.matchIPv6Src(IpPrefix.valueOf(ip));
312 }
313 }
314
315 private class IpV6DstDecoder implements CriterionDecoder {
316 @Override
317 public Criterion decodeCriterion(ObjectNode json) {
318 String ip = nullIsIllegal(json.get(CriterionCodec.IP),
319 CriterionCodec.IP + MISSING_MEMBER_MESSAGE).asText();
320 return Criteria.matchIPv6Dst(IpPrefix.valueOf(ip));
321 }
322 }
323
324 private class TcpSrcDecoder implements CriterionDecoder {
325 @Override
326 public Criterion decodeCriterion(ObjectNode json) {
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700327 TpPort tcpPort = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.TCP_PORT),
328 CriterionCodec.TCP_PORT + MISSING_MEMBER_MESSAGE).asInt());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700329 return Criteria.matchTcpSrc(tcpPort);
330 }
331 }
332
Andreas Gilbert5e959612017-12-20 10:30:18 +0100333 private class TcpSrcMaskDecoder implements CriterionDecoder {
334 @Override
335 public Criterion decodeCriterion(ObjectNode json) {
336 TpPort tcpPort = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.TCP_PORT),
337 CriterionCodec.TCP_PORT + MISSING_MEMBER_MESSAGE).asInt());
338
339 TpPort tcpMask = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.TCP_MASK),
340 CriterionCodec.TCP_MASK + MISSING_MEMBER_MESSAGE).asInt());
341
342 return Criteria.matchTcpSrcMasked(tcpPort, tcpMask);
343 }
344 }
345
Ray Milkeyd43fe452015-05-29 09:35:12 -0700346 private class TcpDstDecoder implements CriterionDecoder {
347 @Override
348 public Criterion decodeCriterion(ObjectNode json) {
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700349 TpPort tcpPort = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.TCP_PORT),
350 CriterionCodec.TCP_PORT + MISSING_MEMBER_MESSAGE).asInt());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700351 return Criteria.matchTcpDst(tcpPort);
352 }
353 }
354
Andreas Gilbert5e959612017-12-20 10:30:18 +0100355 private class TcpDstMaskDecoder implements CriterionDecoder {
356 @Override
357 public Criterion decodeCriterion(ObjectNode json) {
358 TpPort tcpPort = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.TCP_PORT),
359 CriterionCodec.TCP_PORT + MISSING_MEMBER_MESSAGE).asInt());
360
361 TpPort tcpMask = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.TCP_MASK),
362 CriterionCodec.TCP_MASK + MISSING_MEMBER_MESSAGE).asInt());
363
364 return Criteria.matchTcpDstMasked(tcpPort, tcpMask);
365 }
366 }
367
Ray Milkeyd43fe452015-05-29 09:35:12 -0700368 private class UdpSrcDecoder implements CriterionDecoder {
369 @Override
370 public Criterion decodeCriterion(ObjectNode json) {
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700371 TpPort udpPort = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.UDP_PORT),
372 CriterionCodec.UDP_PORT + MISSING_MEMBER_MESSAGE).asInt());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700373 return Criteria.matchUdpSrc(udpPort);
374 }
375 }
376
Andreas Gilbert5e959612017-12-20 10:30:18 +0100377 private class UdpSrcMaskDecoder implements CriterionDecoder {
378 @Override
379 public Criterion decodeCriterion(ObjectNode json) {
380 TpPort udpPort = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.UDP_PORT),
381 CriterionCodec.UDP_PORT + MISSING_MEMBER_MESSAGE).asInt());
382
383 TpPort udpMask = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.UDP_MASK),
384 CriterionCodec.UDP_MASK + MISSING_MEMBER_MESSAGE).asInt());
385
386 return Criteria.matchUdpSrcMasked(udpPort, udpMask);
387 }
388 }
389
Ray Milkeyd43fe452015-05-29 09:35:12 -0700390 private class UdpDstDecoder implements CriterionDecoder {
391 @Override
392 public Criterion decodeCriterion(ObjectNode json) {
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700393 TpPort udpPort = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.UDP_PORT),
394 CriterionCodec.UDP_PORT + MISSING_MEMBER_MESSAGE).asInt());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700395 return Criteria.matchUdpDst(udpPort);
396 }
397 }
398
Andreas Gilbert5e959612017-12-20 10:30:18 +0100399 private class UdpDstMaskDecoder implements CriterionDecoder {
400 @Override
401 public Criterion decodeCriterion(ObjectNode json) {
402 TpPort udpPort = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.UDP_PORT),
403 CriterionCodec.UDP_PORT + MISSING_MEMBER_MESSAGE).asInt());
404
405 TpPort udpMask = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.UDP_MASK),
406 CriterionCodec.UDP_MASK + MISSING_MEMBER_MESSAGE).asInt());
407
408 return Criteria.matchUdpDstMasked(udpPort, udpMask);
409 }
410 }
411
Ray Milkeyd43fe452015-05-29 09:35:12 -0700412 private class SctpSrcDecoder implements CriterionDecoder {
413 @Override
414 public Criterion decodeCriterion(ObjectNode json) {
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700415 TpPort sctpPort = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.SCTP_PORT),
416 CriterionCodec.SCTP_PORT + MISSING_MEMBER_MESSAGE).asInt());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700417 return Criteria.matchSctpSrc(sctpPort);
418 }
419 }
420
Andreas Gilbert5e959612017-12-20 10:30:18 +0100421 private class SctpSrcMaskDecoder implements CriterionDecoder {
422 @Override
423 public Criterion decodeCriterion(ObjectNode json) {
424 TpPort sctpPort = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.SCTP_PORT),
425 CriterionCodec.SCTP_PORT + MISSING_MEMBER_MESSAGE).asInt());
426
427 TpPort sctpMask = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.SCTP_MASK),
428 CriterionCodec.SCTP_MASK + MISSING_MEMBER_MESSAGE).asInt());
429
430 return Criteria.matchSctpSrcMasked(sctpPort, sctpMask);
431 }
432 }
433
Ray Milkeyd43fe452015-05-29 09:35:12 -0700434 private class SctpDstDecoder implements CriterionDecoder {
435 @Override
436 public Criterion decodeCriterion(ObjectNode json) {
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700437 TpPort sctpPort = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.SCTP_PORT),
438 CriterionCodec.SCTP_PORT + MISSING_MEMBER_MESSAGE).asInt());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700439 return Criteria.matchSctpDst(sctpPort);
440 }
441 }
442
Andreas Gilbert5e959612017-12-20 10:30:18 +0100443 private class SctpDstMaskDecoder implements CriterionDecoder {
444 @Override
445 public Criterion decodeCriterion(ObjectNode json) {
446 TpPort sctpPort = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.SCTP_PORT),
447 CriterionCodec.SCTP_PORT + MISSING_MEMBER_MESSAGE).asInt());
448
449 TpPort sctpMask = TpPort.tpPort(nullIsIllegal(json.get(CriterionCodec.SCTP_MASK),
450 CriterionCodec.SCTP_MASK + MISSING_MEMBER_MESSAGE).asInt());
451
452 return Criteria.matchSctpDstMasked(sctpPort, sctpMask);
453 }
454 }
455
Ray Milkeyd43fe452015-05-29 09:35:12 -0700456 private class IcmpV4TypeDecoder implements CriterionDecoder {
457 @Override
458 public Criterion decodeCriterion(ObjectNode json) {
459 short type = (short) nullIsIllegal(json.get(CriterionCodec.ICMP_TYPE),
460 CriterionCodec.ICMP_TYPE + MISSING_MEMBER_MESSAGE).asInt();
461 return Criteria.matchIcmpType(type);
462 }
463 }
464
465 private class IcmpV4CodeDecoder implements CriterionDecoder {
466 @Override
467 public Criterion decodeCriterion(ObjectNode json) {
468 short code = (short) nullIsIllegal(json.get(CriterionCodec.ICMP_CODE),
469 CriterionCodec.ICMP_CODE + MISSING_MEMBER_MESSAGE).asInt();
470 return Criteria.matchIcmpCode(code);
471 }
472 }
473
474 private class IpV6FLabelDecoder implements CriterionDecoder {
475 @Override
476 public Criterion decodeCriterion(ObjectNode json) {
477 int flowLabel = nullIsIllegal(json.get(CriterionCodec.FLOW_LABEL),
478 CriterionCodec.FLOW_LABEL + MISSING_MEMBER_MESSAGE).asInt();
479 return Criteria.matchIPv6FlowLabel(flowLabel);
480 }
481 }
482
483 private class IcmpV6TypeDecoder implements CriterionDecoder {
484 @Override
485 public Criterion decodeCriterion(ObjectNode json) {
486 short type = (short) nullIsIllegal(json.get(CriterionCodec.ICMPV6_TYPE),
487 CriterionCodec.ICMPV6_TYPE + MISSING_MEMBER_MESSAGE).asInt();
488 return Criteria.matchIcmpv6Type(type);
489 }
490 }
491
492 private class IcmpV6CodeDecoder implements CriterionDecoder {
493 @Override
494 public Criterion decodeCriterion(ObjectNode json) {
495 short code = (short) nullIsIllegal(json.get(CriterionCodec.ICMPV6_CODE),
496 CriterionCodec.ICMPV6_CODE + MISSING_MEMBER_MESSAGE).asInt();
497 return Criteria.matchIcmpv6Code(code);
498 }
499 }
500
501 private class V6NDTargetDecoder implements CriterionDecoder {
502 @Override
503 public Criterion decodeCriterion(ObjectNode json) {
504 Ip6Address target = Ip6Address.valueOf(nullIsIllegal(json.get(CriterionCodec.TARGET_ADDRESS),
505 CriterionCodec.TARGET_ADDRESS + MISSING_MEMBER_MESSAGE).asText());
506 return Criteria.matchIPv6NDTargetAddress(target);
507 }
508 }
509
510 private class V6NDSllDecoder implements CriterionDecoder {
511 @Override
512 public Criterion decodeCriterion(ObjectNode json) {
513 MacAddress mac = MacAddress.valueOf(nullIsIllegal(json.get(CriterionCodec.MAC),
514 CriterionCodec.MAC + MISSING_MEMBER_MESSAGE).asText());
515 return Criteria.matchIPv6NDSourceLinkLayerAddress(mac);
516 }
517 }
518
519 private class V6NDTllDecoder implements CriterionDecoder {
520 @Override
521 public Criterion decodeCriterion(ObjectNode json) {
522 MacAddress mac = MacAddress.valueOf(nullIsIllegal(json.get(CriterionCodec.MAC),
523 CriterionCodec.MAC + MISSING_MEMBER_MESSAGE).asText());
524 return Criteria.matchIPv6NDTargetLinkLayerAddress(mac);
525 }
526 }
527
528 private class MplsLabelDecoder implements CriterionDecoder {
529 @Override
530 public Criterion decodeCriterion(ObjectNode json) {
531 int label = nullIsIllegal(json.get(CriterionCodec.LABEL),
532 CriterionCodec.LABEL + MISSING_MEMBER_MESSAGE).asInt();
533 return Criteria.matchMplsLabel(MplsLabel.mplsLabel(label));
534 }
535 }
536
Jonathan Hartcc962d82016-08-09 16:52:22 -0700537 private class MplsBosDecoder implements CriterionDecoder {
538 @Override
539 public Criterion decodeCriterion(ObjectNode json) {
540 boolean bos = nullIsIllegal(json.get(CriterionCodec.BOS),
541 CriterionCodec.BOS + MISSING_MEMBER_MESSAGE).asBoolean();
542 return Criteria.matchMplsBos(bos);
543 }
544 }
545
Ray Milkeyd43fe452015-05-29 09:35:12 -0700546 private class IpV6ExthdrDecoder implements CriterionDecoder {
547 @Override
548 public Criterion decodeCriterion(ObjectNode json) {
549 int exthdrFlags = nullIsIllegal(json.get(CriterionCodec.EXT_HDR_FLAGS),
550 CriterionCodec.EXT_HDR_FLAGS + MISSING_MEMBER_MESSAGE).asInt();
551 return Criteria.matchIPv6ExthdrFlags(exthdrFlags);
552 }
553 }
554
555 private class OchSigIdDecoder implements CriterionDecoder {
556 @Override
557 public Criterion decodeCriterion(ObjectNode json) {
Sho SHIMIZUcc137a92016-03-11 15:10:54 -0800558 JsonNode ochSignalId = nullIsIllegal(json.get(CriterionCodec.OCH_SIGNAL_ID),
559 CriterionCodec.GRID_TYPE + MISSING_MEMBER_MESSAGE);
560 GridType gridType =
561 GridType.valueOf(
562 nullIsIllegal(ochSignalId.get(CriterionCodec.GRID_TYPE),
563 CriterionCodec.GRID_TYPE + MISSING_MEMBER_MESSAGE).asText());
564 ChannelSpacing channelSpacing =
565 ChannelSpacing.valueOf(
566 nullIsIllegal(ochSignalId.get(CriterionCodec.CHANNEL_SPACING),
567 CriterionCodec.CHANNEL_SPACING + MISSING_MEMBER_MESSAGE).asText());
568 int spacingMultiplier = nullIsIllegal(ochSignalId.get(CriterionCodec.SPACING_MULIPLIER),
569 CriterionCodec.SPACING_MULIPLIER + MISSING_MEMBER_MESSAGE).asInt();
570 int slotGranularity = nullIsIllegal(ochSignalId.get(CriterionCodec.SLOT_GRANULARITY),
571 CriterionCodec.SLOT_GRANULARITY + MISSING_MEMBER_MESSAGE).asInt();
572 return Criteria.matchLambda(
573 Lambda.ochSignal(gridType, channelSpacing,
574 spacingMultiplier, slotGranularity));
Ray Milkeyd43fe452015-05-29 09:35:12 -0700575 }
576 }
577
578 private class OchSigTypeDecoder implements CriterionDecoder {
579 @Override
580 public Criterion decodeCriterion(ObjectNode json) {
Yafit Hadar5796d972015-10-15 13:16:11 +0300581 OchSignalType ochSignalType = OchSignalType.valueOf(nullIsIllegal(json.get(CriterionCodec.OCH_SIGNAL_TYPE),
582 CriterionCodec.OCH_SIGNAL_TYPE + MISSING_MEMBER_MESSAGE).asText());
583 return Criteria.matchOchSignalType(ochSignalType);
Ray Milkeyd43fe452015-05-29 09:35:12 -0700584 }
585 }
586
Hyunsun Moon7080a0d2015-08-14 19:18:48 -0700587 private class TunnelIdDecoder implements CriterionDecoder {
588 @Override
589 public Criterion decodeCriterion(ObjectNode json) {
590 long tunnelId = nullIsIllegal(json.get(CriterionCodec.TUNNEL_ID),
591 CriterionCodec.TUNNEL_ID + MISSING_MEMBER_MESSAGE).asLong();
592 return Criteria.matchTunnelId(tunnelId);
593 }
594 }
595
Yafit Hadar5796d972015-10-15 13:16:11 +0300596 private class OduSigIdDecoder implements CriterionDecoder {
597 @Override
598 public Criterion decodeCriterion(ObjectNode json) {
599 JsonNode oduSignalId = nullIsIllegal(json.get(CriterionCodec.ODU_SIGNAL_ID),
600 CriterionCodec.TRIBUTARY_PORT_NUMBER + MISSING_MEMBER_MESSAGE);
601
602 int tributaryPortNumber = nullIsIllegal(oduSignalId.get(CriterionCodec.TRIBUTARY_PORT_NUMBER),
603 CriterionCodec.TRIBUTARY_PORT_NUMBER + MISSING_MEMBER_MESSAGE).asInt();
604 int tributarySlotLen = nullIsIllegal(oduSignalId.get(CriterionCodec.TRIBUTARY_SLOT_LEN),
605 CriterionCodec.TRIBUTARY_SLOT_LEN + MISSING_MEMBER_MESSAGE).asInt();
606 byte[] tributarySlotBitmap = HexString.fromHexString(
607 nullIsIllegal(oduSignalId.get(CriterionCodec.TRIBUTARY_SLOT_BITMAP),
608 CriterionCodec.TRIBUTARY_SLOT_BITMAP + MISSING_MEMBER_MESSAGE).asText());
609
610 return Criteria.matchOduSignalId(
611 OduSignalId.oduSignalId(tributaryPortNumber, tributarySlotLen, tributarySlotBitmap));
612 }
613 }
614
615 private class OduSigTypeDecoder implements CriterionDecoder {
616 @Override
617 public Criterion decodeCriterion(ObjectNode json) {
618 OduSignalType oduSignalType = OduSignalType.valueOf(nullIsIllegal(json.get(CriterionCodec.ODU_SIGNAL_TYPE),
619 CriterionCodec.ODU_SIGNAL_TYPE + MISSING_MEMBER_MESSAGE).asText());
620 return Criteria.matchOduSignalType(oduSignalType);
621 }
622 }
623
Frank Wang74ce2c12018-04-11 20:26:45 +0800624 private class PiDecoder implements CriterionDecoder {
625 @Override
626 public Criterion decodeCriterion(ObjectNode json) {
627 PiCriterion.Builder builder = PiCriterion.builder();
628 JsonNode matchesNode = nullIsIllegal(json.get(CriterionCodec.PI_MATCHES),
629 CriterionCodec.PI_MATCHES + MISSING_MEMBER_MESSAGE);
630 if (matchesNode.isArray()) {
631 for (JsonNode node : matchesNode) {
632 String type = nullIsIllegal(node.get(CriterionCodec.PI_MATCH_TYPE),
633 CriterionCodec.PI_MATCH_TYPE + MISSING_MEMBER_MESSAGE).asText();
634 switch (PiMatchType.valueOf(type.toUpperCase())) {
635 case EXACT:
636 builder.matchExact(
637 PiMatchFieldId.of(
638 nullIsIllegal(node.get(CriterionCodec.PI_MATCH_FIELD_ID),
639 CriterionCodec.PI_MATCH_FIELD_ID +
640 MISSING_MEMBER_MESSAGE).asText()),
641 HexString.fromHexString(nullIsIllegal(node.get(CriterionCodec.PI_MATCH_VALUE),
642 CriterionCodec.PI_MATCH_VALUE +
643 MISSING_MEMBER_MESSAGE).asText(), null));
644 break;
645 case LPM:
646 builder.matchLpm(
647 PiMatchFieldId.of(
648 nullIsIllegal(node.get(CriterionCodec.PI_MATCH_FIELD_ID),
649 CriterionCodec.PI_MATCH_FIELD_ID +
650 MISSING_MEMBER_MESSAGE).asText()),
651 HexString.fromHexString(nullIsIllegal(node.get(CriterionCodec.PI_MATCH_VALUE),
652 CriterionCodec.PI_MATCH_VALUE +
653 MISSING_MEMBER_MESSAGE).asText(), null),
654 nullIsIllegal(node.get(CriterionCodec.PI_MATCH_PREFIX),
655 CriterionCodec.PI_MATCH_PREFIX +
656 MISSING_MEMBER_MESSAGE).asInt());
657 break;
658 case TERNARY:
659 builder.matchTernary(
660 PiMatchFieldId.of(
661 nullIsIllegal(node.get(CriterionCodec.PI_MATCH_FIELD_ID),
662 CriterionCodec.PI_MATCH_FIELD_ID +
663 MISSING_MEMBER_MESSAGE).asText()),
664 HexString.fromHexString(nullIsIllegal(node.get(CriterionCodec.PI_MATCH_VALUE),
665 CriterionCodec.PI_MATCH_VALUE +
666 MISSING_MEMBER_MESSAGE).asText(), null),
667 HexString.fromHexString(nullIsIllegal(node.get(CriterionCodec.PI_MATCH_MASK),
668 CriterionCodec.PI_MATCH_MASK +
669 MISSING_MEMBER_MESSAGE).asText(), null));
670 break;
671 case RANGE:
672 builder.matchRange(
673 PiMatchFieldId.of(
674 nullIsIllegal(node.get(CriterionCodec.PI_MATCH_FIELD_ID),
675 CriterionCodec.PI_MATCH_FIELD_ID +
676 MISSING_MEMBER_MESSAGE).asText()),
677 HexString.fromHexString(nullIsIllegal(node.get(CriterionCodec.PI_MATCH_LOW_VALUE),
678 CriterionCodec.PI_MATCH_LOW_VALUE +
679 MISSING_MEMBER_MESSAGE).asText(), null),
680 HexString.fromHexString(nullIsIllegal(node.get(CriterionCodec.PI_MATCH_HIGH_VALUE),
Daniele Moroc6f2f7f2020-12-18 10:55:57 +0100681 CriterionCodec.PI_MATCH_HIGH_VALUE +
682 MISSING_MEMBER_MESSAGE).asText(), null));
683 break;
684 case OPTIONAL:
685 builder.matchOptional(
686 PiMatchFieldId.of(
687 nullIsIllegal(node.get(CriterionCodec.PI_MATCH_FIELD_ID),
688 CriterionCodec.PI_MATCH_FIELD_ID +
689 MISSING_MEMBER_MESSAGE).asText()),
690 HexString.fromHexString(nullIsIllegal(node.get(CriterionCodec.PI_MATCH_VALUE),
691 CriterionCodec.PI_MATCH_VALUE +
692 MISSING_MEMBER_MESSAGE).asText(), null));
Frank Wang74ce2c12018-04-11 20:26:45 +0800693 break;
Frank Wang74ce2c12018-04-11 20:26:45 +0800694 default:
695 throw new IllegalArgumentException("Type " + type + " is unsupported");
696 }
697 }
698 } else {
699 throw new IllegalArgumentException("Protocol-independent matches must be in an array.");
700 }
701
702 return builder.build();
703 }
704 }
705
Seyeon Jeong8d3cad22020-02-28 01:17:34 -0800706 private class ExtensionDecoder implements CriterionDecoder {
707 @Override
708 public Criterion decodeCriterion(ObjectNode json) {
709 try {
710 byte[] buffer = nullIsIllegal(json.get(CriterionCodec.EXTENSION),
711 CriterionCodec.EXTENSION + MISSING_MEMBER_MESSAGE).binaryValue();
712 Input input = new Input(new ByteArrayInputStream(buffer));
713 ExtensionCriterion extensionCriterion =
714 KryoNamespaces.API.borrow().readObject(input, ExtensionCriterion.class);
715 input.close();
716 return extensionCriterion;
717 } catch (IOException e) {
718 log.warn("Cannot convert the {} field into byte array", CriterionCodec.EXTENSION);
719 return null;
720 }
721 }
722 }
723
Ray Milkeyd43fe452015-05-29 09:35:12 -0700724 /**
725 * Decodes the JSON into a criterion object.
726 *
727 * @return Criterion object
728 * @throws IllegalArgumentException if the JSON is invalid
729 */
730 public Criterion decode() {
Ray Milkey52075062016-02-03 17:36:48 -0800731 String type =
732 nullIsIllegal(json.get(CriterionCodec.TYPE), "Type not specified")
733 .asText();
Ray Milkeyd43fe452015-05-29 09:35:12 -0700734
735 CriterionDecoder decoder = decoderMap.get(type);
736 if (decoder != null) {
737 return decoder.decodeCriterion(json);
738 }
739
740 throw new IllegalArgumentException("Type " + type + " is unknown");
741 }
742
743
744}