blob: 8a3feaac3634caa746e591eb316c02c176422029 [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;
Daniele Moroc6f2f7f2020-12-18 10:55:57 +010059import org.onosproject.net.pi.runtime.PiOptionalFieldMatch;
Frank Wang74ce2c12018-04-11 20:26:45 +080060import org.onosproject.net.pi.runtime.PiRangeFieldMatch;
61import org.onosproject.net.pi.runtime.PiTernaryFieldMatch;
Seyeon Jeong8d3cad22020-02-28 01:17:34 -080062import org.onosproject.store.serializers.KryoNamespaces;
Ray Milkeyd43fe452015-05-29 09:35:12 -070063
Seyeon Jeong8d3cad22020-02-28 01:17:34 -080064import java.io.ByteArrayOutputStream;
andread35f89c2015-11-23 10:02:07 -080065import java.util.EnumMap;
Ray Milkeyd43fe452015-05-29 09:35:12 -070066
67import static com.google.common.base.Preconditions.checkNotNull;
68
69/**
70 * Encode portion of the criterion codec.
71 */
Ray Milkey6d7968e2015-07-06 14:30:02 -070072public final class EncodeCriterionCodecHelper {
Ray Milkeyd43fe452015-05-29 09:35:12 -070073
74 private final Criterion criterion;
75 private final CodecContext context;
76
77 private final EnumMap<Criterion.Type, CriterionTypeFormatter> formatMap;
78
79 /**
80 * Creates an encoder object for a criterion.
81 * Initializes the formatter lookup map for the criterion subclasses.
82 *
83 * @param criterion Criterion to encode
andread35f89c2015-11-23 10:02:07 -080084 * @param context context of the JSON encoding
Ray Milkeyd43fe452015-05-29 09:35:12 -070085 */
Ray Milkey6d7968e2015-07-06 14:30:02 -070086 public EncodeCriterionCodecHelper(Criterion criterion, CodecContext context) {
Ray Milkeyd43fe452015-05-29 09:35:12 -070087 this.criterion = criterion;
88 this.context = context;
89
90 formatMap = new EnumMap<>(Criterion.Type.class);
91
92 formatMap.put(Criterion.Type.IN_PORT, new FormatInPort());
93 formatMap.put(Criterion.Type.IN_PHY_PORT, new FormatInPort());
94 formatMap.put(Criterion.Type.METADATA, new FormatMetadata());
95 formatMap.put(Criterion.Type.ETH_DST, new FormatEth());
Seyeon Jeong8f014142020-02-26 12:51:03 -080096 formatMap.put(Criterion.Type.ETH_DST_MASKED, new FormatEthMasked());
Ray Milkeyd43fe452015-05-29 09:35:12 -070097 formatMap.put(Criterion.Type.ETH_SRC, new FormatEth());
David Glantz6210c4c2021-09-21 15:39:19 -050098 formatMap.put(Criterion.Type.ETH_SRC_MASKED, new FormatEthMasked());
Ray Milkeyd43fe452015-05-29 09:35:12 -070099 formatMap.put(Criterion.Type.ETH_TYPE, new FormatEthType());
100 formatMap.put(Criterion.Type.VLAN_VID, new FormatVlanVid());
101 formatMap.put(Criterion.Type.VLAN_PCP, new FormatVlanPcp());
alshabibfa0dc662016-01-13 11:23:53 -0800102 formatMap.put(Criterion.Type.INNER_VLAN_VID, new FormatInnerVlanVid());
103 formatMap.put(Criterion.Type.INNER_VLAN_PCP, new FormatInnerVlanPcp());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700104 formatMap.put(Criterion.Type.IP_DSCP, new FormatIpDscp());
105 formatMap.put(Criterion.Type.IP_ECN, new FormatIpEcn());
106 formatMap.put(Criterion.Type.IP_PROTO, new FormatIpProto());
107 formatMap.put(Criterion.Type.IPV4_SRC, new FormatIp());
108 formatMap.put(Criterion.Type.IPV4_DST, new FormatIp());
109 formatMap.put(Criterion.Type.TCP_SRC, new FormatTcp());
Andreas Gilbert5e959612017-12-20 10:30:18 +0100110 formatMap.put(Criterion.Type.TCP_SRC_MASKED, new FormatTcpMask());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700111 formatMap.put(Criterion.Type.TCP_DST, new FormatTcp());
Andreas Gilbert5e959612017-12-20 10:30:18 +0100112 formatMap.put(Criterion.Type.TCP_DST_MASKED, new FormatTcpMask());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700113 formatMap.put(Criterion.Type.UDP_SRC, new FormatUdp());
Andreas Gilbert5e959612017-12-20 10:30:18 +0100114 formatMap.put(Criterion.Type.UDP_SRC_MASKED, new FormatUdpMask());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700115 formatMap.put(Criterion.Type.UDP_DST, new FormatUdp());
Andreas Gilbert5e959612017-12-20 10:30:18 +0100116 formatMap.put(Criterion.Type.UDP_DST_MASKED, new FormatUdpMask());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700117 formatMap.put(Criterion.Type.SCTP_SRC, new FormatSctp());
Andreas Gilbert5e959612017-12-20 10:30:18 +0100118 formatMap.put(Criterion.Type.SCTP_SRC_MASKED, new FormatSctpMask());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700119 formatMap.put(Criterion.Type.SCTP_DST, new FormatSctp());
Andreas Gilbert5e959612017-12-20 10:30:18 +0100120 formatMap.put(Criterion.Type.SCTP_DST_MASKED, new FormatSctpMask());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700121 formatMap.put(Criterion.Type.ICMPV4_TYPE, new FormatIcmpV4Type());
122 formatMap.put(Criterion.Type.ICMPV4_CODE, new FormatIcmpV4Code());
123 formatMap.put(Criterion.Type.IPV6_SRC, new FormatIp());
124 formatMap.put(Criterion.Type.IPV6_DST, new FormatIp());
125 formatMap.put(Criterion.Type.IPV6_FLABEL, new FormatIpV6FLabel());
126 formatMap.put(Criterion.Type.ICMPV6_TYPE, new FormatIcmpV6Type());
127 formatMap.put(Criterion.Type.ICMPV6_CODE, new FormatIcmpV6Code());
128 formatMap.put(Criterion.Type.IPV6_ND_TARGET, new FormatV6NDTarget());
129 formatMap.put(Criterion.Type.IPV6_ND_SLL, new FormatV6NDTll());
130 formatMap.put(Criterion.Type.IPV6_ND_TLL, new FormatV6NDTll());
131 formatMap.put(Criterion.Type.MPLS_LABEL, new FormatMplsLabel());
Jonathan Hartcc962d82016-08-09 16:52:22 -0700132 formatMap.put(Criterion.Type.MPLS_BOS, new FormatMplsBos());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700133 formatMap.put(Criterion.Type.IPV6_EXTHDR, new FormatIpV6Exthdr());
134 formatMap.put(Criterion.Type.OCH_SIGID, new FormatOchSigId());
135 formatMap.put(Criterion.Type.OCH_SIGTYPE, new FormatOchSigType());
Hyunsun Moon7080a0d2015-08-14 19:18:48 -0700136 formatMap.put(Criterion.Type.TUNNEL_ID, new FormatTunnelId());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700137 formatMap.put(Criterion.Type.DUMMY, new FormatDummyType());
Yafit Hadar52d81552015-10-07 12:26:52 +0300138 formatMap.put(Criterion.Type.ODU_SIGID, new FormatOduSignalId());
139 formatMap.put(Criterion.Type.ODU_SIGTYPE, new FormatOduSignalType());
Frank Wang74ce2c12018-04-11 20:26:45 +0800140 formatMap.put(Criterion.Type.PROTOCOL_INDEPENDENT, new FormatProtocolIndependent());
Seyeon Jeong8d3cad22020-02-28 01:17:34 -0800141 formatMap.put(Criterion.Type.EXTENSION, new FormatExtension());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700142 // Currently unimplemented
143 formatMap.put(Criterion.Type.ARP_OP, new FormatUnknown());
144 formatMap.put(Criterion.Type.ARP_SPA, new FormatUnknown());
145 formatMap.put(Criterion.Type.ARP_TPA, new FormatUnknown());
146 formatMap.put(Criterion.Type.ARP_SHA, new FormatUnknown());
147 formatMap.put(Criterion.Type.ARP_THA, new FormatUnknown());
148 formatMap.put(Criterion.Type.MPLS_TC, new FormatUnknown());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700149 formatMap.put(Criterion.Type.PBB_ISID, new FormatUnknown());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700150 formatMap.put(Criterion.Type.UNASSIGNED_40, new FormatUnknown());
151 formatMap.put(Criterion.Type.PBB_UCA, new FormatUnknown());
152 formatMap.put(Criterion.Type.TCP_FLAGS, new FormatUnknown());
153 formatMap.put(Criterion.Type.ACTSET_OUTPUT, new FormatUnknown());
154 formatMap.put(Criterion.Type.PACKET_TYPE, new FormatUnknown());
155 }
156
157 private interface CriterionTypeFormatter {
158 ObjectNode encodeCriterion(ObjectNode root, Criterion criterion);
159 }
160
161 private static class FormatUnknown implements CriterionTypeFormatter {
162 @Override
163 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
164 return root;
165 }
166 }
167
168 private static class FormatInPort implements CriterionTypeFormatter {
169 @Override
170 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
171 final PortCriterion portCriterion = (PortCriterion) criterion;
172 return root.put(CriterionCodec.PORT, portCriterion.port().toLong());
173 }
174 }
175
176 private static class FormatMetadata implements CriterionTypeFormatter {
177 @Override
178 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
179 final MetadataCriterion metadataCriterion =
180 (MetadataCriterion) criterion;
181 return root.put(CriterionCodec.METADATA, metadataCriterion.metadata());
182 }
183 }
184
185 private static class FormatEth implements CriterionTypeFormatter {
186 @Override
187 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
188 final EthCriterion ethCriterion = (EthCriterion) criterion;
189 return root.put(CriterionCodec.MAC, ethCriterion.mac().toString());
190 }
191 }
192
Seyeon Jeong8f014142020-02-26 12:51:03 -0800193 private static class FormatEthMasked implements CriterionTypeFormatter {
194 @Override
195 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
196 final EthCriterion ethCriterion = (EthCriterion) criterion;
197 root.put(CriterionCodec.MAC, ethCriterion.mac().toString());
198 root.put(CriterionCodec.MAC_MASK, ethCriterion.mask().toString());
199
200 return root;
201 }
202 }
203
Ray Milkeyd43fe452015-05-29 09:35:12 -0700204 private static class FormatEthType implements CriterionTypeFormatter {
205 @Override
206 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
207 final EthTypeCriterion ethTypeCriterion =
208 (EthTypeCriterion) criterion;
andread35f89c2015-11-23 10:02:07 -0800209 return root.put(CriterionCodec.ETH_TYPE, "0x"
210 + Integer.toHexString(ethTypeCriterion.ethType().toShort() & 0xffff));
Ray Milkeyd43fe452015-05-29 09:35:12 -0700211 }
212 }
213
214 private static class FormatVlanVid implements CriterionTypeFormatter {
215 @Override
216 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
217 final VlanIdCriterion vlanIdCriterion =
218 (VlanIdCriterion) criterion;
219 return root.put(CriterionCodec.VLAN_ID, vlanIdCriterion.vlanId().toShort());
220 }
221 }
222
223 private static class FormatVlanPcp implements CriterionTypeFormatter {
224 @Override
225 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
226 final VlanPcpCriterion vlanPcpCriterion =
227 (VlanPcpCriterion) criterion;
228 return root.put(CriterionCodec.PRIORITY, vlanPcpCriterion.priority());
229 }
230 }
231
alshabibfa0dc662016-01-13 11:23:53 -0800232 private static class FormatInnerVlanVid implements CriterionTypeFormatter {
233 @Override
234 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
235 final VlanIdCriterion vlanIdCriterion =
236 (VlanIdCriterion) criterion;
237 return root.put(CriterionCodec.INNER_VLAN_ID, vlanIdCriterion.vlanId().toShort());
238 }
239 }
240
241 private static class FormatInnerVlanPcp implements CriterionTypeFormatter {
242 @Override
243 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
244 final VlanPcpCriterion vlanPcpCriterion =
245 (VlanPcpCriterion) criterion;
246 return root.put(CriterionCodec.INNER_PRIORITY, vlanPcpCriterion.priority());
247 }
248 }
249
Ray Milkeyd43fe452015-05-29 09:35:12 -0700250 private static class FormatIpDscp implements CriterionTypeFormatter {
251 @Override
252 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
253 final IPDscpCriterion ipDscpCriterion =
254 (IPDscpCriterion) criterion;
255 return root.put(CriterionCodec.IP_DSCP, ipDscpCriterion.ipDscp());
256 }
257 }
258
259 private static class FormatIpEcn implements CriterionTypeFormatter {
260 @Override
261 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
262 final IPEcnCriterion ipEcnCriterion =
263 (IPEcnCriterion) criterion;
264 return root.put(CriterionCodec.IP_ECN, ipEcnCriterion.ipEcn());
265 }
266 }
267
268 private static class FormatIpProto implements CriterionTypeFormatter {
269 @Override
270 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
271 final IPProtocolCriterion iPProtocolCriterion =
272 (IPProtocolCriterion) criterion;
273 return root.put(CriterionCodec.PROTOCOL, iPProtocolCriterion.protocol());
274 }
275 }
276
277 private static class FormatIp implements CriterionTypeFormatter {
278 @Override
279 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
280 final IPCriterion iPCriterion = (IPCriterion) criterion;
281 return root.put(CriterionCodec.IP, iPCriterion.ip().toString());
282 }
283 }
284
285 private static class FormatTcp implements CriterionTypeFormatter {
286 @Override
287 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
288 final TcpPortCriterion tcpPortCriterion =
289 (TcpPortCriterion) criterion;
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700290 return root.put(CriterionCodec.TCP_PORT, tcpPortCriterion.tcpPort().toInt());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700291 }
292 }
293
Andreas Gilbert5e959612017-12-20 10:30:18 +0100294 private static class FormatTcpMask implements CriterionTypeFormatter {
295 @Override
296 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
297 final TcpPortCriterion tcpPortCriterion =
298 (TcpPortCriterion) criterion;
299
300 root.put(CriterionCodec.TCP_PORT, tcpPortCriterion.tcpPort().toInt());
301 root.put(CriterionCodec.TCP_MASK, tcpPortCriterion.mask().toInt());
302
303 return root;
304 }
305 }
306
Ray Milkeyd43fe452015-05-29 09:35:12 -0700307 private static class FormatUdp implements CriterionTypeFormatter {
308 @Override
309 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
310 final UdpPortCriterion udpPortCriterion =
311 (UdpPortCriterion) criterion;
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700312 return root.put(CriterionCodec.UDP_PORT, udpPortCriterion.udpPort().toInt());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700313 }
314 }
315
Andreas Gilbert5e959612017-12-20 10:30:18 +0100316 private static class FormatUdpMask implements CriterionTypeFormatter {
317 @Override
318 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
319 final UdpPortCriterion udpPortCriterion =
320 (UdpPortCriterion) criterion;
321
322 root.put(CriterionCodec.UDP_PORT, udpPortCriterion.udpPort().toInt());
323 root.put(CriterionCodec.UDP_MASK, udpPortCriterion.mask().toInt());
324
325 return root;
326 }
327 }
328
Ray Milkeyd43fe452015-05-29 09:35:12 -0700329 private static class FormatSctp implements CriterionTypeFormatter {
330 @Override
331 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
332 final SctpPortCriterion sctpPortCriterion =
333 (SctpPortCriterion) criterion;
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700334 return root.put(CriterionCodec.SCTP_PORT, sctpPortCriterion.sctpPort().toInt());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700335 }
336 }
337
Andreas Gilbert5e959612017-12-20 10:30:18 +0100338 private static class FormatSctpMask implements CriterionTypeFormatter {
339 @Override
340 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
341 final SctpPortCriterion sctpPortCriterion =
342 (SctpPortCriterion) criterion;
343
344 root.put(CriterionCodec.SCTP_PORT, sctpPortCriterion.sctpPort().toInt());
345 root.put(CriterionCodec.SCTP_MASK, sctpPortCriterion.mask().toInt());
346
347 return root;
348 }
349 }
350
Ray Milkeyd43fe452015-05-29 09:35:12 -0700351 private static class FormatIcmpV4Type implements CriterionTypeFormatter {
352 @Override
353 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
354 final IcmpTypeCriterion icmpTypeCriterion =
355 (IcmpTypeCriterion) criterion;
356 return root.put(CriterionCodec.ICMP_TYPE, icmpTypeCriterion.icmpType());
357 }
358 }
359
360 private static class FormatIcmpV4Code implements CriterionTypeFormatter {
361 @Override
362 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
363 final IcmpCodeCriterion icmpCodeCriterion =
364 (IcmpCodeCriterion) criterion;
365 return root.put(CriterionCodec.ICMP_CODE, icmpCodeCriterion.icmpCode());
366 }
367 }
368
369 private static class FormatIpV6FLabel implements CriterionTypeFormatter {
370 @Override
371 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
372 final IPv6FlowLabelCriterion ipv6FlowLabelCriterion =
373 (IPv6FlowLabelCriterion) criterion;
374 return root.put(CriterionCodec.FLOW_LABEL, ipv6FlowLabelCriterion.flowLabel());
375 }
376 }
377
378 private static class FormatIcmpV6Type implements CriterionTypeFormatter {
379 @Override
380 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
381 final Icmpv6TypeCriterion icmpv6TypeCriterion =
382 (Icmpv6TypeCriterion) criterion;
383 return root.put(CriterionCodec.ICMPV6_TYPE, icmpv6TypeCriterion.icmpv6Type());
384 }
385 }
386
387 private static class FormatIcmpV6Code implements CriterionTypeFormatter {
388 @Override
389 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
390 final Icmpv6CodeCriterion icmpv6CodeCriterion =
391 (Icmpv6CodeCriterion) criterion;
392 return root.put(CriterionCodec.ICMPV6_CODE, icmpv6CodeCriterion.icmpv6Code());
393 }
394 }
395
396 private static class FormatV6NDTarget implements CriterionTypeFormatter {
397 @Override
398 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
399 final IPv6NDTargetAddressCriterion ipv6NDTargetAddressCriterion
400 = (IPv6NDTargetAddressCriterion) criterion;
401 return root.put(CriterionCodec.TARGET_ADDRESS, ipv6NDTargetAddressCriterion.targetAddress().toString());
402 }
403 }
404
405 private static class FormatV6NDTll implements CriterionTypeFormatter {
406 @Override
407 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
408 final IPv6NDLinkLayerAddressCriterion ipv6NDLinkLayerAddressCriterion
409 = (IPv6NDLinkLayerAddressCriterion) criterion;
410 return root.put(CriterionCodec.MAC, ipv6NDLinkLayerAddressCriterion.mac().toString());
411 }
412 }
413
414 private static class FormatMplsLabel implements CriterionTypeFormatter {
415 @Override
416 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
417 final MplsCriterion mplsCriterion =
418 (MplsCriterion) criterion;
419 return root.put(CriterionCodec.LABEL, mplsCriterion.label().toInt());
420 }
421 }
422
Jonathan Hartcc962d82016-08-09 16:52:22 -0700423 private static class FormatMplsBos implements CriterionTypeFormatter {
424 @Override
425 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
426 final MplsBosCriterion mplsBosCriterion =
427 (MplsBosCriterion) criterion;
428 return root.put(CriterionCodec.BOS, mplsBosCriterion.mplsBos());
429 }
430 }
431
Ray Milkeyd43fe452015-05-29 09:35:12 -0700432 private static class FormatIpV6Exthdr implements CriterionTypeFormatter {
433 @Override
434 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
435 final IPv6ExthdrFlagsCriterion exthdrCriterion =
436 (IPv6ExthdrFlagsCriterion) criterion;
437 return root.put(CriterionCodec.EXT_HDR_FLAGS, exthdrCriterion.exthdrFlags());
438 }
439 }
440
441 private static class FormatOchSigId implements CriterionTypeFormatter {
442 @Override
443 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
444 OchSignal ochSignal = ((OchSignalCriterion) criterion).lambda();
445 ObjectNode child = root.putObject(CriterionCodec.OCH_SIGNAL_ID);
446
447 child.put(CriterionCodec.GRID_TYPE, ochSignal.gridType().name());
448 child.put(CriterionCodec.CHANNEL_SPACING, ochSignal.channelSpacing().name());
449 child.put(CriterionCodec.SPACING_MULIPLIER, ochSignal.spacingMultiplier());
450 child.put(CriterionCodec.SLOT_GRANULARITY, ochSignal.slotGranularity());
451
452 return root;
453 }
454 }
455
456 private static class FormatOchSigType implements CriterionTypeFormatter {
457 @Override
458 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
459 final OchSignalTypeCriterion ochSignalTypeCriterion =
460 (OchSignalTypeCriterion) criterion;
Yafit Hadar52d81552015-10-07 12:26:52 +0300461 return root.put(CriterionCodec.OCH_SIGNAL_TYPE, ochSignalTypeCriterion.signalType().name());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700462 }
463 }
464
Hyunsun Moon7080a0d2015-08-14 19:18:48 -0700465 private static class FormatTunnelId implements CriterionTypeFormatter {
466 @Override
467 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
468 final TunnelIdCriterion tunnelIdCriterion =
469 (TunnelIdCriterion) criterion;
470 return root.put(CriterionCodec.TUNNEL_ID, tunnelIdCriterion.tunnelId());
471 }
472 }
473
Yafit Hadar52d81552015-10-07 12:26:52 +0300474 private static class FormatOduSignalId implements CriterionTypeFormatter {
475 @Override
476 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
Yafit Hadar5796d972015-10-15 13:16:11 +0300477 OduSignalId oduSignalId = ((OduSignalIdCriterion) criterion).oduSignalId();
478 ObjectNode child = root.putObject(CriterionCodec.ODU_SIGNAL_ID);
479
480 child.put(CriterionCodec.TRIBUTARY_PORT_NUMBER, oduSignalId.tributaryPortNumber());
481 child.put(CriterionCodec.TRIBUTARY_SLOT_LEN, oduSignalId.tributarySlotLength());
482 child.put(CriterionCodec.TRIBUTARY_SLOT_BITMAP, HexString.toHexString(oduSignalId.tributarySlotBitmap()));
483
484 return root;
Yafit Hadar52d81552015-10-07 12:26:52 +0300485 }
486 }
487
Yafit Hadar5796d972015-10-15 13:16:11 +0300488
Yafit Hadar52d81552015-10-07 12:26:52 +0300489 private static class FormatOduSignalType implements CriterionTypeFormatter {
490 @Override
491 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
492 final OduSignalTypeCriterion oduSignalTypeCriterion =
493 (OduSignalTypeCriterion) criterion;
494 return root.put(CriterionCodec.ODU_SIGNAL_TYPE, oduSignalTypeCriterion.signalType().name());
495 }
496 }
497
Frank Wang74ce2c12018-04-11 20:26:45 +0800498 private ObjectNode parsePiMatchExact(PiExactFieldMatch exactFieldMatch) {
499
500 ObjectNode matchExactNode = context.mapper().createObjectNode();
501 matchExactNode.put(CriterionCodec.PI_MATCH_FIELD_ID, exactFieldMatch.fieldId().id());
502 matchExactNode.put(CriterionCodec.PI_MATCH_TYPE, PiMatchType.EXACT.name().toLowerCase());
503 matchExactNode.put(CriterionCodec.PI_MATCH_VALUE,
504 HexString.toHexString(exactFieldMatch.value().asArray(),
505 null));
506 return matchExactNode;
507 }
508
509 private ObjectNode parsePiMatchLpm(PiLpmFieldMatch lpmFieldMatch) {
510
511 ObjectNode matchLpmNode = context.mapper().createObjectNode();
512 matchLpmNode.put(CriterionCodec.PI_MATCH_FIELD_ID, lpmFieldMatch.fieldId().id());
513 matchLpmNode.put(CriterionCodec.PI_MATCH_TYPE, PiMatchType.LPM.name().toLowerCase());
514 matchLpmNode.put(CriterionCodec.PI_MATCH_VALUE,
515 HexString.toHexString(lpmFieldMatch.value().asArray(),
516 null));
517 matchLpmNode.put(CriterionCodec.PI_MATCH_PREFIX, lpmFieldMatch.prefixLength());
518
519 return matchLpmNode;
520 }
521
522 private ObjectNode parsePiMatchTernary(PiTernaryFieldMatch ternaryFieldMatch) {
523
524 ObjectNode matchTernaryNode = context.mapper().createObjectNode();
525 matchTernaryNode.put(CriterionCodec.PI_MATCH_FIELD_ID, ternaryFieldMatch.fieldId().id());
526 matchTernaryNode.put(CriterionCodec.PI_MATCH_TYPE, PiMatchType.TERNARY.name().toLowerCase());
527 matchTernaryNode.put(CriterionCodec.PI_MATCH_VALUE,
528 HexString.toHexString(ternaryFieldMatch.value().asArray(),
529 null));
530 matchTernaryNode.put(CriterionCodec.PI_MATCH_MASK,
531 HexString.toHexString(ternaryFieldMatch.mask().asArray(),
532 null));
533
534 return matchTernaryNode;
535 }
536
537 private ObjectNode parsePiMatchRange(PiRangeFieldMatch rangeFieldMatch) {
538
539 ObjectNode matchRangeNode = context.mapper().createObjectNode();
540 matchRangeNode.put(CriterionCodec.PI_MATCH_FIELD_ID, rangeFieldMatch.fieldId().id());
541 matchRangeNode.put(CriterionCodec.PI_MATCH_TYPE, PiMatchType.RANGE.name().toLowerCase());
542 matchRangeNode.put(CriterionCodec.PI_MATCH_HIGH_VALUE,
543 HexString.toHexString(rangeFieldMatch.highValue().asArray(),
544 null));
545 matchRangeNode.put(CriterionCodec.PI_MATCH_LOW_VALUE,
546 HexString.toHexString(rangeFieldMatch.lowValue().asArray(),
547 null));
548
549 return matchRangeNode;
550 }
551
Daniele Moroc6f2f7f2020-12-18 10:55:57 +0100552 private ObjectNode parsePiMatchOptional(PiOptionalFieldMatch optionalFieldMatch) {
553
554 ObjectNode optionalExactNode = context.mapper().createObjectNode();
555 optionalExactNode.put(CriterionCodec.PI_MATCH_FIELD_ID, optionalFieldMatch.fieldId().id());
556 optionalExactNode.put(CriterionCodec.PI_MATCH_TYPE, PiMatchType.OPTIONAL.name().toLowerCase());
557 optionalExactNode.put(CriterionCodec.PI_MATCH_VALUE,
558 HexString.toHexString(optionalFieldMatch.value().asArray(),
559 null));
560 return optionalExactNode;
561 }
562
Frank Wang74ce2c12018-04-11 20:26:45 +0800563 private class FormatProtocolIndependent implements CriterionTypeFormatter {
564 @Override
565 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
566 final PiCriterion piCriterion = (PiCriterion) criterion;
567 ArrayNode matchNodes = context.mapper().createArrayNode();
568 for (PiFieldMatch fieldMatch : piCriterion.fieldMatches()) {
569 switch (fieldMatch.type()) {
570 case EXACT:
571 matchNodes.add(parsePiMatchExact((PiExactFieldMatch) fieldMatch));
572 break;
573 case LPM:
574 matchNodes.add(parsePiMatchLpm((PiLpmFieldMatch) fieldMatch));
575 break;
576 case TERNARY:
577 matchNodes.add(parsePiMatchTernary((PiTernaryFieldMatch) fieldMatch));
578 break;
579 case RANGE:
Frank Wang74ce2c12018-04-11 20:26:45 +0800580 matchNodes.add(parsePiMatchRange((PiRangeFieldMatch) fieldMatch));
581 break;
Daniele Moroc6f2f7f2020-12-18 10:55:57 +0100582 case OPTIONAL:
583 matchNodes.add(parsePiMatchOptional((PiOptionalFieldMatch) fieldMatch));
584 break;
Frank Wang74ce2c12018-04-11 20:26:45 +0800585 default:
586 throw new IllegalArgumentException("Type " + fieldMatch.type().name() + " is unsupported");
587 }
588 }
589 return (ObjectNode) root.set(CriterionCodec.PI_MATCHES, matchNodes);
590 }
591 }
592
Seyeon Jeong8d3cad22020-02-28 01:17:34 -0800593 private class FormatExtension implements CriterionTypeFormatter {
594 @Override
595 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
596 Output output = new Output(new ByteArrayOutputStream());
597 KryoNamespaces.API.borrow().writeObject(output, criterion);
598 root.put(CriterionCodec.EXTENSION, output.toBytes());
599 output.flush();
600 output.close();
601
602 return root;
603 }
604 }
605
Ray Milkeyd43fe452015-05-29 09:35:12 -0700606 private class FormatDummyType implements CriterionTypeFormatter {
607
608 @Override
609 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
610 checkNotNull(criterion, "Criterion cannot be null");
611
612 return root.put(CriterionCodec.TYPE, criterion.type().toString());
613
614 }
615 }
616
617 /**
618 * Encodes a criterion into a JSON node.
619 *
620 * @return encoded JSON object for the given criterion
621 */
622 public ObjectNode encode() {
623 final ObjectNode result = context.mapper().createObjectNode()
624 .put(CriterionCodec.TYPE, criterion.type().toString());
625
626 CriterionTypeFormatter formatter =
627 checkNotNull(
628 formatMap.get(criterion.type()),
629 "No formatter found for criterion type "
630 + criterion.type().toString());
631
632 return formatter.encodeCriterion(result, criterion);
633 }
634
635}