blob: c99e3535b3f1fa669641f404f8c29863fac13fc2 [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.Output;
Frank Wang74ce2c12018-04-11 20:26:45 +080019import com.fasterxml.jackson.databind.node.ArrayNode;
andread35f89c2015-11-23 10:02:07 -080020import com.fasterxml.jackson.databind.node.ObjectNode;
Yafit Hadar5796d972015-10-15 13:16:11 +030021import org.onlab.util.HexString;
Ray Milkeyd43fe452015-05-29 09:35:12 -070022import org.onosproject.codec.CodecContext;
23import org.onosproject.net.OchSignal;
Yafit Hadar5796d972015-10-15 13:16:11 +030024import org.onosproject.net.OduSignalId;
Ray Milkeyd43fe452015-05-29 09:35:12 -070025import org.onosproject.net.flow.criteria.Criterion;
26import org.onosproject.net.flow.criteria.EthCriterion;
27import org.onosproject.net.flow.criteria.EthTypeCriterion;
28import org.onosproject.net.flow.criteria.IPCriterion;
29import org.onosproject.net.flow.criteria.IPDscpCriterion;
30import org.onosproject.net.flow.criteria.IPEcnCriterion;
31import org.onosproject.net.flow.criteria.IPProtocolCriterion;
32import org.onosproject.net.flow.criteria.IPv6ExthdrFlagsCriterion;
33import org.onosproject.net.flow.criteria.IPv6FlowLabelCriterion;
34import org.onosproject.net.flow.criteria.IPv6NDLinkLayerAddressCriterion;
35import org.onosproject.net.flow.criteria.IPv6NDTargetAddressCriterion;
36import org.onosproject.net.flow.criteria.IcmpCodeCriterion;
37import org.onosproject.net.flow.criteria.IcmpTypeCriterion;
38import org.onosproject.net.flow.criteria.Icmpv6CodeCriterion;
39import org.onosproject.net.flow.criteria.Icmpv6TypeCriterion;
40import org.onosproject.net.flow.criteria.MetadataCriterion;
Jonathan Hartcc962d82016-08-09 16:52:22 -070041import org.onosproject.net.flow.criteria.MplsBosCriterion;
Ray Milkeyd43fe452015-05-29 09:35:12 -070042import org.onosproject.net.flow.criteria.MplsCriterion;
43import org.onosproject.net.flow.criteria.OchSignalCriterion;
44import org.onosproject.net.flow.criteria.OchSignalTypeCriterion;
Yafit Hadar52d81552015-10-07 12:26:52 +030045import org.onosproject.net.flow.criteria.OduSignalIdCriterion;
46import org.onosproject.net.flow.criteria.OduSignalTypeCriterion;
Frank Wang74ce2c12018-04-11 20:26:45 +080047import org.onosproject.net.flow.criteria.PiCriterion;
Ray Milkeyd43fe452015-05-29 09:35:12 -070048import org.onosproject.net.flow.criteria.PortCriterion;
49import org.onosproject.net.flow.criteria.SctpPortCriterion;
50import org.onosproject.net.flow.criteria.TcpPortCriterion;
Hyunsun Moon7080a0d2015-08-14 19:18:48 -070051import org.onosproject.net.flow.criteria.TunnelIdCriterion;
Ray Milkeyd43fe452015-05-29 09:35:12 -070052import org.onosproject.net.flow.criteria.UdpPortCriterion;
53import org.onosproject.net.flow.criteria.VlanIdCriterion;
54import org.onosproject.net.flow.criteria.VlanPcpCriterion;
Frank Wang74ce2c12018-04-11 20:26:45 +080055import org.onosproject.net.pi.model.PiMatchType;
56import org.onosproject.net.pi.runtime.PiExactFieldMatch;
57import org.onosproject.net.pi.runtime.PiFieldMatch;
58import org.onosproject.net.pi.runtime.PiLpmFieldMatch;
59import org.onosproject.net.pi.runtime.PiRangeFieldMatch;
60import org.onosproject.net.pi.runtime.PiTernaryFieldMatch;
Seyeon Jeong8d3cad22020-02-28 01:17:34 -080061import org.onosproject.store.serializers.KryoNamespaces;
Ray Milkeyd43fe452015-05-29 09:35:12 -070062
Seyeon Jeong8d3cad22020-02-28 01:17:34 -080063import java.io.ByteArrayOutputStream;
andread35f89c2015-11-23 10:02:07 -080064import java.util.EnumMap;
Ray Milkeyd43fe452015-05-29 09:35:12 -070065
66import static com.google.common.base.Preconditions.checkNotNull;
67
68/**
69 * Encode portion of the criterion codec.
70 */
Ray Milkey6d7968e2015-07-06 14:30:02 -070071public final class EncodeCriterionCodecHelper {
Ray Milkeyd43fe452015-05-29 09:35:12 -070072
73 private final Criterion criterion;
74 private final CodecContext context;
75
76 private final EnumMap<Criterion.Type, CriterionTypeFormatter> formatMap;
77
78 /**
79 * Creates an encoder object for a criterion.
80 * Initializes the formatter lookup map for the criterion subclasses.
81 *
82 * @param criterion Criterion to encode
andread35f89c2015-11-23 10:02:07 -080083 * @param context context of the JSON encoding
Ray Milkeyd43fe452015-05-29 09:35:12 -070084 */
Ray Milkey6d7968e2015-07-06 14:30:02 -070085 public EncodeCriterionCodecHelper(Criterion criterion, CodecContext context) {
Ray Milkeyd43fe452015-05-29 09:35:12 -070086 this.criterion = criterion;
87 this.context = context;
88
89 formatMap = new EnumMap<>(Criterion.Type.class);
90
91 formatMap.put(Criterion.Type.IN_PORT, new FormatInPort());
92 formatMap.put(Criterion.Type.IN_PHY_PORT, new FormatInPort());
93 formatMap.put(Criterion.Type.METADATA, new FormatMetadata());
94 formatMap.put(Criterion.Type.ETH_DST, new FormatEth());
Seyeon Jeong8f014142020-02-26 12:51:03 -080095 formatMap.put(Criterion.Type.ETH_DST_MASKED, new FormatEthMasked());
Ray Milkeyd43fe452015-05-29 09:35:12 -070096 formatMap.put(Criterion.Type.ETH_SRC, new FormatEth());
97 formatMap.put(Criterion.Type.ETH_TYPE, new FormatEthType());
98 formatMap.put(Criterion.Type.VLAN_VID, new FormatVlanVid());
99 formatMap.put(Criterion.Type.VLAN_PCP, new FormatVlanPcp());
alshabibfa0dc662016-01-13 11:23:53 -0800100 formatMap.put(Criterion.Type.INNER_VLAN_VID, new FormatInnerVlanVid());
101 formatMap.put(Criterion.Type.INNER_VLAN_PCP, new FormatInnerVlanPcp());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700102 formatMap.put(Criterion.Type.IP_DSCP, new FormatIpDscp());
103 formatMap.put(Criterion.Type.IP_ECN, new FormatIpEcn());
104 formatMap.put(Criterion.Type.IP_PROTO, new FormatIpProto());
105 formatMap.put(Criterion.Type.IPV4_SRC, new FormatIp());
106 formatMap.put(Criterion.Type.IPV4_DST, new FormatIp());
107 formatMap.put(Criterion.Type.TCP_SRC, new FormatTcp());
Andreas Gilbert5e959612017-12-20 10:30:18 +0100108 formatMap.put(Criterion.Type.TCP_SRC_MASKED, new FormatTcpMask());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700109 formatMap.put(Criterion.Type.TCP_DST, new FormatTcp());
Andreas Gilbert5e959612017-12-20 10:30:18 +0100110 formatMap.put(Criterion.Type.TCP_DST_MASKED, new FormatTcpMask());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700111 formatMap.put(Criterion.Type.UDP_SRC, new FormatUdp());
Andreas Gilbert5e959612017-12-20 10:30:18 +0100112 formatMap.put(Criterion.Type.UDP_SRC_MASKED, new FormatUdpMask());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700113 formatMap.put(Criterion.Type.UDP_DST, new FormatUdp());
Andreas Gilbert5e959612017-12-20 10:30:18 +0100114 formatMap.put(Criterion.Type.UDP_DST_MASKED, new FormatUdpMask());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700115 formatMap.put(Criterion.Type.SCTP_SRC, new FormatSctp());
Andreas Gilbert5e959612017-12-20 10:30:18 +0100116 formatMap.put(Criterion.Type.SCTP_SRC_MASKED, new FormatSctpMask());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700117 formatMap.put(Criterion.Type.SCTP_DST, new FormatSctp());
Andreas Gilbert5e959612017-12-20 10:30:18 +0100118 formatMap.put(Criterion.Type.SCTP_DST_MASKED, new FormatSctpMask());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700119 formatMap.put(Criterion.Type.ICMPV4_TYPE, new FormatIcmpV4Type());
120 formatMap.put(Criterion.Type.ICMPV4_CODE, new FormatIcmpV4Code());
121 formatMap.put(Criterion.Type.IPV6_SRC, new FormatIp());
122 formatMap.put(Criterion.Type.IPV6_DST, new FormatIp());
123 formatMap.put(Criterion.Type.IPV6_FLABEL, new FormatIpV6FLabel());
124 formatMap.put(Criterion.Type.ICMPV6_TYPE, new FormatIcmpV6Type());
125 formatMap.put(Criterion.Type.ICMPV6_CODE, new FormatIcmpV6Code());
126 formatMap.put(Criterion.Type.IPV6_ND_TARGET, new FormatV6NDTarget());
127 formatMap.put(Criterion.Type.IPV6_ND_SLL, new FormatV6NDTll());
128 formatMap.put(Criterion.Type.IPV6_ND_TLL, new FormatV6NDTll());
129 formatMap.put(Criterion.Type.MPLS_LABEL, new FormatMplsLabel());
Jonathan Hartcc962d82016-08-09 16:52:22 -0700130 formatMap.put(Criterion.Type.MPLS_BOS, new FormatMplsBos());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700131 formatMap.put(Criterion.Type.IPV6_EXTHDR, new FormatIpV6Exthdr());
132 formatMap.put(Criterion.Type.OCH_SIGID, new FormatOchSigId());
133 formatMap.put(Criterion.Type.OCH_SIGTYPE, new FormatOchSigType());
Hyunsun Moon7080a0d2015-08-14 19:18:48 -0700134 formatMap.put(Criterion.Type.TUNNEL_ID, new FormatTunnelId());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700135 formatMap.put(Criterion.Type.DUMMY, new FormatDummyType());
Yafit Hadar52d81552015-10-07 12:26:52 +0300136 formatMap.put(Criterion.Type.ODU_SIGID, new FormatOduSignalId());
137 formatMap.put(Criterion.Type.ODU_SIGTYPE, new FormatOduSignalType());
Frank Wang74ce2c12018-04-11 20:26:45 +0800138 formatMap.put(Criterion.Type.PROTOCOL_INDEPENDENT, new FormatProtocolIndependent());
Seyeon Jeong8d3cad22020-02-28 01:17:34 -0800139 formatMap.put(Criterion.Type.EXTENSION, new FormatExtension());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700140 // Currently unimplemented
141 formatMap.put(Criterion.Type.ARP_OP, new FormatUnknown());
142 formatMap.put(Criterion.Type.ARP_SPA, new FormatUnknown());
143 formatMap.put(Criterion.Type.ARP_TPA, new FormatUnknown());
144 formatMap.put(Criterion.Type.ARP_SHA, new FormatUnknown());
145 formatMap.put(Criterion.Type.ARP_THA, new FormatUnknown());
146 formatMap.put(Criterion.Type.MPLS_TC, new FormatUnknown());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700147 formatMap.put(Criterion.Type.PBB_ISID, new FormatUnknown());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700148 formatMap.put(Criterion.Type.UNASSIGNED_40, new FormatUnknown());
149 formatMap.put(Criterion.Type.PBB_UCA, new FormatUnknown());
150 formatMap.put(Criterion.Type.TCP_FLAGS, new FormatUnknown());
151 formatMap.put(Criterion.Type.ACTSET_OUTPUT, new FormatUnknown());
152 formatMap.put(Criterion.Type.PACKET_TYPE, new FormatUnknown());
Saurav Das9d6c86b2016-02-19 09:01:07 -0800153 formatMap.put(Criterion.Type.ETH_SRC_MASKED, new FormatUnknown());
Andreas Gilbert75b882f72017-02-03 09:58:07 +0100154 formatMap.put(Criterion.Type.TCP_SRC_MASKED, new FormatUnknown());
155 formatMap.put(Criterion.Type.TCP_DST_MASKED, new FormatUnknown());
156 formatMap.put(Criterion.Type.UDP_SRC_MASKED, new FormatUnknown());
157 formatMap.put(Criterion.Type.UDP_DST_MASKED, new FormatUnknown());
158 formatMap.put(Criterion.Type.SCTP_SRC_MASKED, new FormatUnknown());
159 formatMap.put(Criterion.Type.SCTP_DST_MASKED, new FormatUnknown());
Saurav Das9d6c86b2016-02-19 09:01:07 -0800160
Ray Milkeyd43fe452015-05-29 09:35:12 -0700161 }
162
163 private interface CriterionTypeFormatter {
164 ObjectNode encodeCriterion(ObjectNode root, Criterion criterion);
165 }
166
167 private static class FormatUnknown implements CriterionTypeFormatter {
168 @Override
169 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
170 return root;
171 }
172 }
173
174 private static class FormatInPort implements CriterionTypeFormatter {
175 @Override
176 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
177 final PortCriterion portCriterion = (PortCriterion) criterion;
178 return root.put(CriterionCodec.PORT, portCriterion.port().toLong());
179 }
180 }
181
182 private static class FormatMetadata implements CriterionTypeFormatter {
183 @Override
184 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
185 final MetadataCriterion metadataCriterion =
186 (MetadataCriterion) criterion;
187 return root.put(CriterionCodec.METADATA, metadataCriterion.metadata());
188 }
189 }
190
191 private static class FormatEth implements CriterionTypeFormatter {
192 @Override
193 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
194 final EthCriterion ethCriterion = (EthCriterion) criterion;
195 return root.put(CriterionCodec.MAC, ethCriterion.mac().toString());
196 }
197 }
198
Seyeon Jeong8f014142020-02-26 12:51:03 -0800199 private static class FormatEthMasked implements CriterionTypeFormatter {
200 @Override
201 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
202 final EthCriterion ethCriterion = (EthCriterion) criterion;
203 root.put(CriterionCodec.MAC, ethCriterion.mac().toString());
204 root.put(CriterionCodec.MAC_MASK, ethCriterion.mask().toString());
205
206 return root;
207 }
208 }
209
Ray Milkeyd43fe452015-05-29 09:35:12 -0700210 private static class FormatEthType implements CriterionTypeFormatter {
211 @Override
212 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
213 final EthTypeCriterion ethTypeCriterion =
214 (EthTypeCriterion) criterion;
andread35f89c2015-11-23 10:02:07 -0800215 return root.put(CriterionCodec.ETH_TYPE, "0x"
216 + Integer.toHexString(ethTypeCriterion.ethType().toShort() & 0xffff));
Ray Milkeyd43fe452015-05-29 09:35:12 -0700217 }
218 }
219
220 private static class FormatVlanVid implements CriterionTypeFormatter {
221 @Override
222 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
223 final VlanIdCriterion vlanIdCriterion =
224 (VlanIdCriterion) criterion;
225 return root.put(CriterionCodec.VLAN_ID, vlanIdCriterion.vlanId().toShort());
226 }
227 }
228
229 private static class FormatVlanPcp implements CriterionTypeFormatter {
230 @Override
231 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
232 final VlanPcpCriterion vlanPcpCriterion =
233 (VlanPcpCriterion) criterion;
234 return root.put(CriterionCodec.PRIORITY, vlanPcpCriterion.priority());
235 }
236 }
237
alshabibfa0dc662016-01-13 11:23:53 -0800238 private static class FormatInnerVlanVid implements CriterionTypeFormatter {
239 @Override
240 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
241 final VlanIdCriterion vlanIdCriterion =
242 (VlanIdCriterion) criterion;
243 return root.put(CriterionCodec.INNER_VLAN_ID, vlanIdCriterion.vlanId().toShort());
244 }
245 }
246
247 private static class FormatInnerVlanPcp implements CriterionTypeFormatter {
248 @Override
249 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
250 final VlanPcpCriterion vlanPcpCriterion =
251 (VlanPcpCriterion) criterion;
252 return root.put(CriterionCodec.INNER_PRIORITY, vlanPcpCriterion.priority());
253 }
254 }
255
Ray Milkeyd43fe452015-05-29 09:35:12 -0700256 private static class FormatIpDscp implements CriterionTypeFormatter {
257 @Override
258 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
259 final IPDscpCriterion ipDscpCriterion =
260 (IPDscpCriterion) criterion;
261 return root.put(CriterionCodec.IP_DSCP, ipDscpCriterion.ipDscp());
262 }
263 }
264
265 private static class FormatIpEcn implements CriterionTypeFormatter {
266 @Override
267 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
268 final IPEcnCriterion ipEcnCriterion =
269 (IPEcnCriterion) criterion;
270 return root.put(CriterionCodec.IP_ECN, ipEcnCriterion.ipEcn());
271 }
272 }
273
274 private static class FormatIpProto implements CriterionTypeFormatter {
275 @Override
276 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
277 final IPProtocolCriterion iPProtocolCriterion =
278 (IPProtocolCriterion) criterion;
279 return root.put(CriterionCodec.PROTOCOL, iPProtocolCriterion.protocol());
280 }
281 }
282
283 private static class FormatIp implements CriterionTypeFormatter {
284 @Override
285 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
286 final IPCriterion iPCriterion = (IPCriterion) criterion;
287 return root.put(CriterionCodec.IP, iPCriterion.ip().toString());
288 }
289 }
290
291 private static class FormatTcp implements CriterionTypeFormatter {
292 @Override
293 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
294 final TcpPortCriterion tcpPortCriterion =
295 (TcpPortCriterion) criterion;
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700296 return root.put(CriterionCodec.TCP_PORT, tcpPortCriterion.tcpPort().toInt());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700297 }
298 }
299
Andreas Gilbert5e959612017-12-20 10:30:18 +0100300 private static class FormatTcpMask implements CriterionTypeFormatter {
301 @Override
302 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
303 final TcpPortCriterion tcpPortCriterion =
304 (TcpPortCriterion) criterion;
305
306 root.put(CriterionCodec.TCP_PORT, tcpPortCriterion.tcpPort().toInt());
307 root.put(CriterionCodec.TCP_MASK, tcpPortCriterion.mask().toInt());
308
309 return root;
310 }
311 }
312
Ray Milkeyd43fe452015-05-29 09:35:12 -0700313 private static class FormatUdp implements CriterionTypeFormatter {
314 @Override
315 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
316 final UdpPortCriterion udpPortCriterion =
317 (UdpPortCriterion) criterion;
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700318 return root.put(CriterionCodec.UDP_PORT, udpPortCriterion.udpPort().toInt());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700319 }
320 }
321
Andreas Gilbert5e959612017-12-20 10:30:18 +0100322 private static class FormatUdpMask implements CriterionTypeFormatter {
323 @Override
324 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
325 final UdpPortCriterion udpPortCriterion =
326 (UdpPortCriterion) criterion;
327
328 root.put(CriterionCodec.UDP_PORT, udpPortCriterion.udpPort().toInt());
329 root.put(CriterionCodec.UDP_MASK, udpPortCriterion.mask().toInt());
330
331 return root;
332 }
333 }
334
Ray Milkeyd43fe452015-05-29 09:35:12 -0700335 private static class FormatSctp implements CriterionTypeFormatter {
336 @Override
337 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
338 final SctpPortCriterion sctpPortCriterion =
339 (SctpPortCriterion) criterion;
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700340 return root.put(CriterionCodec.SCTP_PORT, sctpPortCriterion.sctpPort().toInt());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700341 }
342 }
343
Andreas Gilbert5e959612017-12-20 10:30:18 +0100344 private static class FormatSctpMask implements CriterionTypeFormatter {
345 @Override
346 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
347 final SctpPortCriterion sctpPortCriterion =
348 (SctpPortCriterion) criterion;
349
350 root.put(CriterionCodec.SCTP_PORT, sctpPortCriterion.sctpPort().toInt());
351 root.put(CriterionCodec.SCTP_MASK, sctpPortCriterion.mask().toInt());
352
353 return root;
354 }
355 }
356
Ray Milkeyd43fe452015-05-29 09:35:12 -0700357 private static class FormatIcmpV4Type implements CriterionTypeFormatter {
358 @Override
359 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
360 final IcmpTypeCriterion icmpTypeCriterion =
361 (IcmpTypeCriterion) criterion;
362 return root.put(CriterionCodec.ICMP_TYPE, icmpTypeCriterion.icmpType());
363 }
364 }
365
366 private static class FormatIcmpV4Code implements CriterionTypeFormatter {
367 @Override
368 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
369 final IcmpCodeCriterion icmpCodeCriterion =
370 (IcmpCodeCriterion) criterion;
371 return root.put(CriterionCodec.ICMP_CODE, icmpCodeCriterion.icmpCode());
372 }
373 }
374
375 private static class FormatIpV6FLabel implements CriterionTypeFormatter {
376 @Override
377 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
378 final IPv6FlowLabelCriterion ipv6FlowLabelCriterion =
379 (IPv6FlowLabelCriterion) criterion;
380 return root.put(CriterionCodec.FLOW_LABEL, ipv6FlowLabelCriterion.flowLabel());
381 }
382 }
383
384 private static class FormatIcmpV6Type implements CriterionTypeFormatter {
385 @Override
386 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
387 final Icmpv6TypeCriterion icmpv6TypeCriterion =
388 (Icmpv6TypeCriterion) criterion;
389 return root.put(CriterionCodec.ICMPV6_TYPE, icmpv6TypeCriterion.icmpv6Type());
390 }
391 }
392
393 private static class FormatIcmpV6Code implements CriterionTypeFormatter {
394 @Override
395 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
396 final Icmpv6CodeCriterion icmpv6CodeCriterion =
397 (Icmpv6CodeCriterion) criterion;
398 return root.put(CriterionCodec.ICMPV6_CODE, icmpv6CodeCriterion.icmpv6Code());
399 }
400 }
401
402 private static class FormatV6NDTarget implements CriterionTypeFormatter {
403 @Override
404 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
405 final IPv6NDTargetAddressCriterion ipv6NDTargetAddressCriterion
406 = (IPv6NDTargetAddressCriterion) criterion;
407 return root.put(CriterionCodec.TARGET_ADDRESS, ipv6NDTargetAddressCriterion.targetAddress().toString());
408 }
409 }
410
411 private static class FormatV6NDTll implements CriterionTypeFormatter {
412 @Override
413 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
414 final IPv6NDLinkLayerAddressCriterion ipv6NDLinkLayerAddressCriterion
415 = (IPv6NDLinkLayerAddressCriterion) criterion;
416 return root.put(CriterionCodec.MAC, ipv6NDLinkLayerAddressCriterion.mac().toString());
417 }
418 }
419
420 private static class FormatMplsLabel implements CriterionTypeFormatter {
421 @Override
422 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
423 final MplsCriterion mplsCriterion =
424 (MplsCriterion) criterion;
425 return root.put(CriterionCodec.LABEL, mplsCriterion.label().toInt());
426 }
427 }
428
Jonathan Hartcc962d82016-08-09 16:52:22 -0700429 private static class FormatMplsBos implements CriterionTypeFormatter {
430 @Override
431 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
432 final MplsBosCriterion mplsBosCriterion =
433 (MplsBosCriterion) criterion;
434 return root.put(CriterionCodec.BOS, mplsBosCriterion.mplsBos());
435 }
436 }
437
Ray Milkeyd43fe452015-05-29 09:35:12 -0700438 private static class FormatIpV6Exthdr implements CriterionTypeFormatter {
439 @Override
440 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
441 final IPv6ExthdrFlagsCriterion exthdrCriterion =
442 (IPv6ExthdrFlagsCriterion) criterion;
443 return root.put(CriterionCodec.EXT_HDR_FLAGS, exthdrCriterion.exthdrFlags());
444 }
445 }
446
447 private static class FormatOchSigId implements CriterionTypeFormatter {
448 @Override
449 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
450 OchSignal ochSignal = ((OchSignalCriterion) criterion).lambda();
451 ObjectNode child = root.putObject(CriterionCodec.OCH_SIGNAL_ID);
452
453 child.put(CriterionCodec.GRID_TYPE, ochSignal.gridType().name());
454 child.put(CriterionCodec.CHANNEL_SPACING, ochSignal.channelSpacing().name());
455 child.put(CriterionCodec.SPACING_MULIPLIER, ochSignal.spacingMultiplier());
456 child.put(CriterionCodec.SLOT_GRANULARITY, ochSignal.slotGranularity());
457
458 return root;
459 }
460 }
461
462 private static class FormatOchSigType implements CriterionTypeFormatter {
463 @Override
464 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
465 final OchSignalTypeCriterion ochSignalTypeCriterion =
466 (OchSignalTypeCriterion) criterion;
Yafit Hadar52d81552015-10-07 12:26:52 +0300467 return root.put(CriterionCodec.OCH_SIGNAL_TYPE, ochSignalTypeCriterion.signalType().name());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700468 }
469 }
470
Hyunsun Moon7080a0d2015-08-14 19:18:48 -0700471 private static class FormatTunnelId implements CriterionTypeFormatter {
472 @Override
473 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
474 final TunnelIdCriterion tunnelIdCriterion =
475 (TunnelIdCriterion) criterion;
476 return root.put(CriterionCodec.TUNNEL_ID, tunnelIdCriterion.tunnelId());
477 }
478 }
479
Yafit Hadar52d81552015-10-07 12:26:52 +0300480 private static class FormatOduSignalId implements CriterionTypeFormatter {
481 @Override
482 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
Yafit Hadar5796d972015-10-15 13:16:11 +0300483 OduSignalId oduSignalId = ((OduSignalIdCriterion) criterion).oduSignalId();
484 ObjectNode child = root.putObject(CriterionCodec.ODU_SIGNAL_ID);
485
486 child.put(CriterionCodec.TRIBUTARY_PORT_NUMBER, oduSignalId.tributaryPortNumber());
487 child.put(CriterionCodec.TRIBUTARY_SLOT_LEN, oduSignalId.tributarySlotLength());
488 child.put(CriterionCodec.TRIBUTARY_SLOT_BITMAP, HexString.toHexString(oduSignalId.tributarySlotBitmap()));
489
490 return root;
Yafit Hadar52d81552015-10-07 12:26:52 +0300491 }
492 }
493
Yafit Hadar5796d972015-10-15 13:16:11 +0300494
Yafit Hadar52d81552015-10-07 12:26:52 +0300495 private static class FormatOduSignalType implements CriterionTypeFormatter {
496 @Override
497 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
498 final OduSignalTypeCriterion oduSignalTypeCriterion =
499 (OduSignalTypeCriterion) criterion;
500 return root.put(CriterionCodec.ODU_SIGNAL_TYPE, oduSignalTypeCriterion.signalType().name());
501 }
502 }
503
Frank Wang74ce2c12018-04-11 20:26:45 +0800504 private ObjectNode parsePiMatchExact(PiExactFieldMatch exactFieldMatch) {
505
506 ObjectNode matchExactNode = context.mapper().createObjectNode();
507 matchExactNode.put(CriterionCodec.PI_MATCH_FIELD_ID, exactFieldMatch.fieldId().id());
508 matchExactNode.put(CriterionCodec.PI_MATCH_TYPE, PiMatchType.EXACT.name().toLowerCase());
509 matchExactNode.put(CriterionCodec.PI_MATCH_VALUE,
510 HexString.toHexString(exactFieldMatch.value().asArray(),
511 null));
512 return matchExactNode;
513 }
514
515 private ObjectNode parsePiMatchLpm(PiLpmFieldMatch lpmFieldMatch) {
516
517 ObjectNode matchLpmNode = context.mapper().createObjectNode();
518 matchLpmNode.put(CriterionCodec.PI_MATCH_FIELD_ID, lpmFieldMatch.fieldId().id());
519 matchLpmNode.put(CriterionCodec.PI_MATCH_TYPE, PiMatchType.LPM.name().toLowerCase());
520 matchLpmNode.put(CriterionCodec.PI_MATCH_VALUE,
521 HexString.toHexString(lpmFieldMatch.value().asArray(),
522 null));
523 matchLpmNode.put(CriterionCodec.PI_MATCH_PREFIX, lpmFieldMatch.prefixLength());
524
525 return matchLpmNode;
526 }
527
528 private ObjectNode parsePiMatchTernary(PiTernaryFieldMatch ternaryFieldMatch) {
529
530 ObjectNode matchTernaryNode = context.mapper().createObjectNode();
531 matchTernaryNode.put(CriterionCodec.PI_MATCH_FIELD_ID, ternaryFieldMatch.fieldId().id());
532 matchTernaryNode.put(CriterionCodec.PI_MATCH_TYPE, PiMatchType.TERNARY.name().toLowerCase());
533 matchTernaryNode.put(CriterionCodec.PI_MATCH_VALUE,
534 HexString.toHexString(ternaryFieldMatch.value().asArray(),
535 null));
536 matchTernaryNode.put(CriterionCodec.PI_MATCH_MASK,
537 HexString.toHexString(ternaryFieldMatch.mask().asArray(),
538 null));
539
540 return matchTernaryNode;
541 }
542
543 private ObjectNode parsePiMatchRange(PiRangeFieldMatch rangeFieldMatch) {
544
545 ObjectNode matchRangeNode = context.mapper().createObjectNode();
546 matchRangeNode.put(CriterionCodec.PI_MATCH_FIELD_ID, rangeFieldMatch.fieldId().id());
547 matchRangeNode.put(CriterionCodec.PI_MATCH_TYPE, PiMatchType.RANGE.name().toLowerCase());
548 matchRangeNode.put(CriterionCodec.PI_MATCH_HIGH_VALUE,
549 HexString.toHexString(rangeFieldMatch.highValue().asArray(),
550 null));
551 matchRangeNode.put(CriterionCodec.PI_MATCH_LOW_VALUE,
552 HexString.toHexString(rangeFieldMatch.lowValue().asArray(),
553 null));
554
555 return matchRangeNode;
556 }
557
Frank Wang74ce2c12018-04-11 20:26:45 +0800558 private class FormatProtocolIndependent implements CriterionTypeFormatter {
559 @Override
560 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
561 final PiCriterion piCriterion = (PiCriterion) criterion;
562 ArrayNode matchNodes = context.mapper().createArrayNode();
563 for (PiFieldMatch fieldMatch : piCriterion.fieldMatches()) {
564 switch (fieldMatch.type()) {
565 case EXACT:
566 matchNodes.add(parsePiMatchExact((PiExactFieldMatch) fieldMatch));
567 break;
568 case LPM:
569 matchNodes.add(parsePiMatchLpm((PiLpmFieldMatch) fieldMatch));
570 break;
571 case TERNARY:
572 matchNodes.add(parsePiMatchTernary((PiTernaryFieldMatch) fieldMatch));
573 break;
574 case RANGE:
Frank Wang74ce2c12018-04-11 20:26:45 +0800575 matchNodes.add(parsePiMatchRange((PiRangeFieldMatch) fieldMatch));
576 break;
Frank Wang74ce2c12018-04-11 20:26:45 +0800577 default:
578 throw new IllegalArgumentException("Type " + fieldMatch.type().name() + " is unsupported");
579 }
580 }
581 return (ObjectNode) root.set(CriterionCodec.PI_MATCHES, matchNodes);
582 }
583 }
584
Seyeon Jeong8d3cad22020-02-28 01:17:34 -0800585 private class FormatExtension implements CriterionTypeFormatter {
586 @Override
587 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
588 Output output = new Output(new ByteArrayOutputStream());
589 KryoNamespaces.API.borrow().writeObject(output, criterion);
590 root.put(CriterionCodec.EXTENSION, output.toBytes());
591 output.flush();
592 output.close();
593
594 return root;
595 }
596 }
597
Ray Milkeyd43fe452015-05-29 09:35:12 -0700598 private class FormatDummyType implements CriterionTypeFormatter {
599
600 @Override
601 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
602 checkNotNull(criterion, "Criterion cannot be null");
603
604 return root.put(CriterionCodec.TYPE, criterion.type().toString());
605
606 }
607 }
608
609 /**
610 * Encodes a criterion into a JSON node.
611 *
612 * @return encoded JSON object for the given criterion
613 */
614 public ObjectNode encode() {
615 final ObjectNode result = context.mapper().createObjectNode()
616 .put(CriterionCodec.TYPE, criterion.type().toString());
617
618 CriterionTypeFormatter formatter =
619 checkNotNull(
620 formatMap.get(criterion.type()),
621 "No formatter found for criterion type "
622 + criterion.type().toString());
623
624 return formatter.encodeCriterion(result, criterion);
625 }
626
627}