blob: 03cab28550d19d4fd0e7fb266a3af001091ef4f3 [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());
98 formatMap.put(Criterion.Type.ETH_TYPE, new FormatEthType());
99 formatMap.put(Criterion.Type.VLAN_VID, new FormatVlanVid());
100 formatMap.put(Criterion.Type.VLAN_PCP, new FormatVlanPcp());
alshabibfa0dc662016-01-13 11:23:53 -0800101 formatMap.put(Criterion.Type.INNER_VLAN_VID, new FormatInnerVlanVid());
102 formatMap.put(Criterion.Type.INNER_VLAN_PCP, new FormatInnerVlanPcp());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700103 formatMap.put(Criterion.Type.IP_DSCP, new FormatIpDscp());
104 formatMap.put(Criterion.Type.IP_ECN, new FormatIpEcn());
105 formatMap.put(Criterion.Type.IP_PROTO, new FormatIpProto());
106 formatMap.put(Criterion.Type.IPV4_SRC, new FormatIp());
107 formatMap.put(Criterion.Type.IPV4_DST, new FormatIp());
108 formatMap.put(Criterion.Type.TCP_SRC, new FormatTcp());
Andreas Gilbert5e959612017-12-20 10:30:18 +0100109 formatMap.put(Criterion.Type.TCP_SRC_MASKED, new FormatTcpMask());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700110 formatMap.put(Criterion.Type.TCP_DST, new FormatTcp());
Andreas Gilbert5e959612017-12-20 10:30:18 +0100111 formatMap.put(Criterion.Type.TCP_DST_MASKED, new FormatTcpMask());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700112 formatMap.put(Criterion.Type.UDP_SRC, new FormatUdp());
Andreas Gilbert5e959612017-12-20 10:30:18 +0100113 formatMap.put(Criterion.Type.UDP_SRC_MASKED, new FormatUdpMask());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700114 formatMap.put(Criterion.Type.UDP_DST, new FormatUdp());
Andreas Gilbert5e959612017-12-20 10:30:18 +0100115 formatMap.put(Criterion.Type.UDP_DST_MASKED, new FormatUdpMask());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700116 formatMap.put(Criterion.Type.SCTP_SRC, new FormatSctp());
Andreas Gilbert5e959612017-12-20 10:30:18 +0100117 formatMap.put(Criterion.Type.SCTP_SRC_MASKED, new FormatSctpMask());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700118 formatMap.put(Criterion.Type.SCTP_DST, new FormatSctp());
Andreas Gilbert5e959612017-12-20 10:30:18 +0100119 formatMap.put(Criterion.Type.SCTP_DST_MASKED, new FormatSctpMask());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700120 formatMap.put(Criterion.Type.ICMPV4_TYPE, new FormatIcmpV4Type());
121 formatMap.put(Criterion.Type.ICMPV4_CODE, new FormatIcmpV4Code());
122 formatMap.put(Criterion.Type.IPV6_SRC, new FormatIp());
123 formatMap.put(Criterion.Type.IPV6_DST, new FormatIp());
124 formatMap.put(Criterion.Type.IPV6_FLABEL, new FormatIpV6FLabel());
125 formatMap.put(Criterion.Type.ICMPV6_TYPE, new FormatIcmpV6Type());
126 formatMap.put(Criterion.Type.ICMPV6_CODE, new FormatIcmpV6Code());
127 formatMap.put(Criterion.Type.IPV6_ND_TARGET, new FormatV6NDTarget());
128 formatMap.put(Criterion.Type.IPV6_ND_SLL, new FormatV6NDTll());
129 formatMap.put(Criterion.Type.IPV6_ND_TLL, new FormatV6NDTll());
130 formatMap.put(Criterion.Type.MPLS_LABEL, new FormatMplsLabel());
Jonathan Hartcc962d82016-08-09 16:52:22 -0700131 formatMap.put(Criterion.Type.MPLS_BOS, new FormatMplsBos());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700132 formatMap.put(Criterion.Type.IPV6_EXTHDR, new FormatIpV6Exthdr());
133 formatMap.put(Criterion.Type.OCH_SIGID, new FormatOchSigId());
134 formatMap.put(Criterion.Type.OCH_SIGTYPE, new FormatOchSigType());
Hyunsun Moon7080a0d2015-08-14 19:18:48 -0700135 formatMap.put(Criterion.Type.TUNNEL_ID, new FormatTunnelId());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700136 formatMap.put(Criterion.Type.DUMMY, new FormatDummyType());
Yafit Hadar52d81552015-10-07 12:26:52 +0300137 formatMap.put(Criterion.Type.ODU_SIGID, new FormatOduSignalId());
138 formatMap.put(Criterion.Type.ODU_SIGTYPE, new FormatOduSignalType());
Frank Wang74ce2c12018-04-11 20:26:45 +0800139 formatMap.put(Criterion.Type.PROTOCOL_INDEPENDENT, new FormatProtocolIndependent());
Seyeon Jeong8d3cad22020-02-28 01:17:34 -0800140 formatMap.put(Criterion.Type.EXTENSION, new FormatExtension());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700141 // Currently unimplemented
142 formatMap.put(Criterion.Type.ARP_OP, new FormatUnknown());
143 formatMap.put(Criterion.Type.ARP_SPA, new FormatUnknown());
144 formatMap.put(Criterion.Type.ARP_TPA, new FormatUnknown());
145 formatMap.put(Criterion.Type.ARP_SHA, new FormatUnknown());
146 formatMap.put(Criterion.Type.ARP_THA, new FormatUnknown());
147 formatMap.put(Criterion.Type.MPLS_TC, new FormatUnknown());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700148 formatMap.put(Criterion.Type.PBB_ISID, new FormatUnknown());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700149 formatMap.put(Criterion.Type.UNASSIGNED_40, new FormatUnknown());
150 formatMap.put(Criterion.Type.PBB_UCA, new FormatUnknown());
151 formatMap.put(Criterion.Type.TCP_FLAGS, new FormatUnknown());
152 formatMap.put(Criterion.Type.ACTSET_OUTPUT, new FormatUnknown());
153 formatMap.put(Criterion.Type.PACKET_TYPE, new FormatUnknown());
Saurav Das9d6c86b2016-02-19 09:01:07 -0800154 formatMap.put(Criterion.Type.ETH_SRC_MASKED, new FormatUnknown());
Andreas Gilbert75b882f72017-02-03 09:58:07 +0100155 formatMap.put(Criterion.Type.TCP_SRC_MASKED, new FormatUnknown());
156 formatMap.put(Criterion.Type.TCP_DST_MASKED, new FormatUnknown());
157 formatMap.put(Criterion.Type.UDP_SRC_MASKED, new FormatUnknown());
158 formatMap.put(Criterion.Type.UDP_DST_MASKED, new FormatUnknown());
159 formatMap.put(Criterion.Type.SCTP_SRC_MASKED, new FormatUnknown());
160 formatMap.put(Criterion.Type.SCTP_DST_MASKED, new FormatUnknown());
Saurav Das9d6c86b2016-02-19 09:01:07 -0800161
Ray Milkeyd43fe452015-05-29 09:35:12 -0700162 }
163
164 private interface CriterionTypeFormatter {
165 ObjectNode encodeCriterion(ObjectNode root, Criterion criterion);
166 }
167
168 private static class FormatUnknown implements CriterionTypeFormatter {
169 @Override
170 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
171 return root;
172 }
173 }
174
175 private static class FormatInPort implements CriterionTypeFormatter {
176 @Override
177 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
178 final PortCriterion portCriterion = (PortCriterion) criterion;
179 return root.put(CriterionCodec.PORT, portCriterion.port().toLong());
180 }
181 }
182
183 private static class FormatMetadata implements CriterionTypeFormatter {
184 @Override
185 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
186 final MetadataCriterion metadataCriterion =
187 (MetadataCriterion) criterion;
188 return root.put(CriterionCodec.METADATA, metadataCriterion.metadata());
189 }
190 }
191
192 private static class FormatEth implements CriterionTypeFormatter {
193 @Override
194 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
195 final EthCriterion ethCriterion = (EthCriterion) criterion;
196 return root.put(CriterionCodec.MAC, ethCriterion.mac().toString());
197 }
198 }
199
Seyeon Jeong8f014142020-02-26 12:51:03 -0800200 private static class FormatEthMasked implements CriterionTypeFormatter {
201 @Override
202 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
203 final EthCriterion ethCriterion = (EthCriterion) criterion;
204 root.put(CriterionCodec.MAC, ethCriterion.mac().toString());
205 root.put(CriterionCodec.MAC_MASK, ethCriterion.mask().toString());
206
207 return root;
208 }
209 }
210
Ray Milkeyd43fe452015-05-29 09:35:12 -0700211 private static class FormatEthType implements CriterionTypeFormatter {
212 @Override
213 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
214 final EthTypeCriterion ethTypeCriterion =
215 (EthTypeCriterion) criterion;
andread35f89c2015-11-23 10:02:07 -0800216 return root.put(CriterionCodec.ETH_TYPE, "0x"
217 + Integer.toHexString(ethTypeCriterion.ethType().toShort() & 0xffff));
Ray Milkeyd43fe452015-05-29 09:35:12 -0700218 }
219 }
220
221 private static class FormatVlanVid implements CriterionTypeFormatter {
222 @Override
223 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
224 final VlanIdCriterion vlanIdCriterion =
225 (VlanIdCriterion) criterion;
226 return root.put(CriterionCodec.VLAN_ID, vlanIdCriterion.vlanId().toShort());
227 }
228 }
229
230 private static class FormatVlanPcp implements CriterionTypeFormatter {
231 @Override
232 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
233 final VlanPcpCriterion vlanPcpCriterion =
234 (VlanPcpCriterion) criterion;
235 return root.put(CriterionCodec.PRIORITY, vlanPcpCriterion.priority());
236 }
237 }
238
alshabibfa0dc662016-01-13 11:23:53 -0800239 private static class FormatInnerVlanVid implements CriterionTypeFormatter {
240 @Override
241 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
242 final VlanIdCriterion vlanIdCriterion =
243 (VlanIdCriterion) criterion;
244 return root.put(CriterionCodec.INNER_VLAN_ID, vlanIdCriterion.vlanId().toShort());
245 }
246 }
247
248 private static class FormatInnerVlanPcp implements CriterionTypeFormatter {
249 @Override
250 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
251 final VlanPcpCriterion vlanPcpCriterion =
252 (VlanPcpCriterion) criterion;
253 return root.put(CriterionCodec.INNER_PRIORITY, vlanPcpCriterion.priority());
254 }
255 }
256
Ray Milkeyd43fe452015-05-29 09:35:12 -0700257 private static class FormatIpDscp implements CriterionTypeFormatter {
258 @Override
259 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
260 final IPDscpCriterion ipDscpCriterion =
261 (IPDscpCriterion) criterion;
262 return root.put(CriterionCodec.IP_DSCP, ipDscpCriterion.ipDscp());
263 }
264 }
265
266 private static class FormatIpEcn implements CriterionTypeFormatter {
267 @Override
268 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
269 final IPEcnCriterion ipEcnCriterion =
270 (IPEcnCriterion) criterion;
271 return root.put(CriterionCodec.IP_ECN, ipEcnCriterion.ipEcn());
272 }
273 }
274
275 private static class FormatIpProto implements CriterionTypeFormatter {
276 @Override
277 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
278 final IPProtocolCriterion iPProtocolCriterion =
279 (IPProtocolCriterion) criterion;
280 return root.put(CriterionCodec.PROTOCOL, iPProtocolCriterion.protocol());
281 }
282 }
283
284 private static class FormatIp implements CriterionTypeFormatter {
285 @Override
286 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
287 final IPCriterion iPCriterion = (IPCriterion) criterion;
288 return root.put(CriterionCodec.IP, iPCriterion.ip().toString());
289 }
290 }
291
292 private static class FormatTcp implements CriterionTypeFormatter {
293 @Override
294 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
295 final TcpPortCriterion tcpPortCriterion =
296 (TcpPortCriterion) criterion;
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700297 return root.put(CriterionCodec.TCP_PORT, tcpPortCriterion.tcpPort().toInt());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700298 }
299 }
300
Andreas Gilbert5e959612017-12-20 10:30:18 +0100301 private static class FormatTcpMask implements CriterionTypeFormatter {
302 @Override
303 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
304 final TcpPortCriterion tcpPortCriterion =
305 (TcpPortCriterion) criterion;
306
307 root.put(CriterionCodec.TCP_PORT, tcpPortCriterion.tcpPort().toInt());
308 root.put(CriterionCodec.TCP_MASK, tcpPortCriterion.mask().toInt());
309
310 return root;
311 }
312 }
313
Ray Milkeyd43fe452015-05-29 09:35:12 -0700314 private static class FormatUdp implements CriterionTypeFormatter {
315 @Override
316 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
317 final UdpPortCriterion udpPortCriterion =
318 (UdpPortCriterion) criterion;
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700319 return root.put(CriterionCodec.UDP_PORT, udpPortCriterion.udpPort().toInt());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700320 }
321 }
322
Andreas Gilbert5e959612017-12-20 10:30:18 +0100323 private static class FormatUdpMask implements CriterionTypeFormatter {
324 @Override
325 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
326 final UdpPortCriterion udpPortCriterion =
327 (UdpPortCriterion) criterion;
328
329 root.put(CriterionCodec.UDP_PORT, udpPortCriterion.udpPort().toInt());
330 root.put(CriterionCodec.UDP_MASK, udpPortCriterion.mask().toInt());
331
332 return root;
333 }
334 }
335
Ray Milkeyd43fe452015-05-29 09:35:12 -0700336 private static class FormatSctp implements CriterionTypeFormatter {
337 @Override
338 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
339 final SctpPortCriterion sctpPortCriterion =
340 (SctpPortCriterion) criterion;
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700341 return root.put(CriterionCodec.SCTP_PORT, sctpPortCriterion.sctpPort().toInt());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700342 }
343 }
344
Andreas Gilbert5e959612017-12-20 10:30:18 +0100345 private static class FormatSctpMask implements CriterionTypeFormatter {
346 @Override
347 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
348 final SctpPortCriterion sctpPortCriterion =
349 (SctpPortCriterion) criterion;
350
351 root.put(CriterionCodec.SCTP_PORT, sctpPortCriterion.sctpPort().toInt());
352 root.put(CriterionCodec.SCTP_MASK, sctpPortCriterion.mask().toInt());
353
354 return root;
355 }
356 }
357
Ray Milkeyd43fe452015-05-29 09:35:12 -0700358 private static class FormatIcmpV4Type implements CriterionTypeFormatter {
359 @Override
360 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
361 final IcmpTypeCriterion icmpTypeCriterion =
362 (IcmpTypeCriterion) criterion;
363 return root.put(CriterionCodec.ICMP_TYPE, icmpTypeCriterion.icmpType());
364 }
365 }
366
367 private static class FormatIcmpV4Code implements CriterionTypeFormatter {
368 @Override
369 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
370 final IcmpCodeCriterion icmpCodeCriterion =
371 (IcmpCodeCriterion) criterion;
372 return root.put(CriterionCodec.ICMP_CODE, icmpCodeCriterion.icmpCode());
373 }
374 }
375
376 private static class FormatIpV6FLabel implements CriterionTypeFormatter {
377 @Override
378 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
379 final IPv6FlowLabelCriterion ipv6FlowLabelCriterion =
380 (IPv6FlowLabelCriterion) criterion;
381 return root.put(CriterionCodec.FLOW_LABEL, ipv6FlowLabelCriterion.flowLabel());
382 }
383 }
384
385 private static class FormatIcmpV6Type implements CriterionTypeFormatter {
386 @Override
387 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
388 final Icmpv6TypeCriterion icmpv6TypeCriterion =
389 (Icmpv6TypeCriterion) criterion;
390 return root.put(CriterionCodec.ICMPV6_TYPE, icmpv6TypeCriterion.icmpv6Type());
391 }
392 }
393
394 private static class FormatIcmpV6Code implements CriterionTypeFormatter {
395 @Override
396 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
397 final Icmpv6CodeCriterion icmpv6CodeCriterion =
398 (Icmpv6CodeCriterion) criterion;
399 return root.put(CriterionCodec.ICMPV6_CODE, icmpv6CodeCriterion.icmpv6Code());
400 }
401 }
402
403 private static class FormatV6NDTarget implements CriterionTypeFormatter {
404 @Override
405 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
406 final IPv6NDTargetAddressCriterion ipv6NDTargetAddressCriterion
407 = (IPv6NDTargetAddressCriterion) criterion;
408 return root.put(CriterionCodec.TARGET_ADDRESS, ipv6NDTargetAddressCriterion.targetAddress().toString());
409 }
410 }
411
412 private static class FormatV6NDTll implements CriterionTypeFormatter {
413 @Override
414 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
415 final IPv6NDLinkLayerAddressCriterion ipv6NDLinkLayerAddressCriterion
416 = (IPv6NDLinkLayerAddressCriterion) criterion;
417 return root.put(CriterionCodec.MAC, ipv6NDLinkLayerAddressCriterion.mac().toString());
418 }
419 }
420
421 private static class FormatMplsLabel implements CriterionTypeFormatter {
422 @Override
423 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
424 final MplsCriterion mplsCriterion =
425 (MplsCriterion) criterion;
426 return root.put(CriterionCodec.LABEL, mplsCriterion.label().toInt());
427 }
428 }
429
Jonathan Hartcc962d82016-08-09 16:52:22 -0700430 private static class FormatMplsBos implements CriterionTypeFormatter {
431 @Override
432 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
433 final MplsBosCriterion mplsBosCriterion =
434 (MplsBosCriterion) criterion;
435 return root.put(CriterionCodec.BOS, mplsBosCriterion.mplsBos());
436 }
437 }
438
Ray Milkeyd43fe452015-05-29 09:35:12 -0700439 private static class FormatIpV6Exthdr implements CriterionTypeFormatter {
440 @Override
441 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
442 final IPv6ExthdrFlagsCriterion exthdrCriterion =
443 (IPv6ExthdrFlagsCriterion) criterion;
444 return root.put(CriterionCodec.EXT_HDR_FLAGS, exthdrCriterion.exthdrFlags());
445 }
446 }
447
448 private static class FormatOchSigId implements CriterionTypeFormatter {
449 @Override
450 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
451 OchSignal ochSignal = ((OchSignalCriterion) criterion).lambda();
452 ObjectNode child = root.putObject(CriterionCodec.OCH_SIGNAL_ID);
453
454 child.put(CriterionCodec.GRID_TYPE, ochSignal.gridType().name());
455 child.put(CriterionCodec.CHANNEL_SPACING, ochSignal.channelSpacing().name());
456 child.put(CriterionCodec.SPACING_MULIPLIER, ochSignal.spacingMultiplier());
457 child.put(CriterionCodec.SLOT_GRANULARITY, ochSignal.slotGranularity());
458
459 return root;
460 }
461 }
462
463 private static class FormatOchSigType implements CriterionTypeFormatter {
464 @Override
465 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
466 final OchSignalTypeCriterion ochSignalTypeCriterion =
467 (OchSignalTypeCriterion) criterion;
Yafit Hadar52d81552015-10-07 12:26:52 +0300468 return root.put(CriterionCodec.OCH_SIGNAL_TYPE, ochSignalTypeCriterion.signalType().name());
Ray Milkeyd43fe452015-05-29 09:35:12 -0700469 }
470 }
471
Hyunsun Moon7080a0d2015-08-14 19:18:48 -0700472 private static class FormatTunnelId implements CriterionTypeFormatter {
473 @Override
474 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
475 final TunnelIdCriterion tunnelIdCriterion =
476 (TunnelIdCriterion) criterion;
477 return root.put(CriterionCodec.TUNNEL_ID, tunnelIdCriterion.tunnelId());
478 }
479 }
480
Yafit Hadar52d81552015-10-07 12:26:52 +0300481 private static class FormatOduSignalId implements CriterionTypeFormatter {
482 @Override
483 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
Yafit Hadar5796d972015-10-15 13:16:11 +0300484 OduSignalId oduSignalId = ((OduSignalIdCriterion) criterion).oduSignalId();
485 ObjectNode child = root.putObject(CriterionCodec.ODU_SIGNAL_ID);
486
487 child.put(CriterionCodec.TRIBUTARY_PORT_NUMBER, oduSignalId.tributaryPortNumber());
488 child.put(CriterionCodec.TRIBUTARY_SLOT_LEN, oduSignalId.tributarySlotLength());
489 child.put(CriterionCodec.TRIBUTARY_SLOT_BITMAP, HexString.toHexString(oduSignalId.tributarySlotBitmap()));
490
491 return root;
Yafit Hadar52d81552015-10-07 12:26:52 +0300492 }
493 }
494
Yafit Hadar5796d972015-10-15 13:16:11 +0300495
Yafit Hadar52d81552015-10-07 12:26:52 +0300496 private static class FormatOduSignalType implements CriterionTypeFormatter {
497 @Override
498 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
499 final OduSignalTypeCriterion oduSignalTypeCriterion =
500 (OduSignalTypeCriterion) criterion;
501 return root.put(CriterionCodec.ODU_SIGNAL_TYPE, oduSignalTypeCriterion.signalType().name());
502 }
503 }
504
Frank Wang74ce2c12018-04-11 20:26:45 +0800505 private ObjectNode parsePiMatchExact(PiExactFieldMatch exactFieldMatch) {
506
507 ObjectNode matchExactNode = context.mapper().createObjectNode();
508 matchExactNode.put(CriterionCodec.PI_MATCH_FIELD_ID, exactFieldMatch.fieldId().id());
509 matchExactNode.put(CriterionCodec.PI_MATCH_TYPE, PiMatchType.EXACT.name().toLowerCase());
510 matchExactNode.put(CriterionCodec.PI_MATCH_VALUE,
511 HexString.toHexString(exactFieldMatch.value().asArray(),
512 null));
513 return matchExactNode;
514 }
515
516 private ObjectNode parsePiMatchLpm(PiLpmFieldMatch lpmFieldMatch) {
517
518 ObjectNode matchLpmNode = context.mapper().createObjectNode();
519 matchLpmNode.put(CriterionCodec.PI_MATCH_FIELD_ID, lpmFieldMatch.fieldId().id());
520 matchLpmNode.put(CriterionCodec.PI_MATCH_TYPE, PiMatchType.LPM.name().toLowerCase());
521 matchLpmNode.put(CriterionCodec.PI_MATCH_VALUE,
522 HexString.toHexString(lpmFieldMatch.value().asArray(),
523 null));
524 matchLpmNode.put(CriterionCodec.PI_MATCH_PREFIX, lpmFieldMatch.prefixLength());
525
526 return matchLpmNode;
527 }
528
529 private ObjectNode parsePiMatchTernary(PiTernaryFieldMatch ternaryFieldMatch) {
530
531 ObjectNode matchTernaryNode = context.mapper().createObjectNode();
532 matchTernaryNode.put(CriterionCodec.PI_MATCH_FIELD_ID, ternaryFieldMatch.fieldId().id());
533 matchTernaryNode.put(CriterionCodec.PI_MATCH_TYPE, PiMatchType.TERNARY.name().toLowerCase());
534 matchTernaryNode.put(CriterionCodec.PI_MATCH_VALUE,
535 HexString.toHexString(ternaryFieldMatch.value().asArray(),
536 null));
537 matchTernaryNode.put(CriterionCodec.PI_MATCH_MASK,
538 HexString.toHexString(ternaryFieldMatch.mask().asArray(),
539 null));
540
541 return matchTernaryNode;
542 }
543
544 private ObjectNode parsePiMatchRange(PiRangeFieldMatch rangeFieldMatch) {
545
546 ObjectNode matchRangeNode = context.mapper().createObjectNode();
547 matchRangeNode.put(CriterionCodec.PI_MATCH_FIELD_ID, rangeFieldMatch.fieldId().id());
548 matchRangeNode.put(CriterionCodec.PI_MATCH_TYPE, PiMatchType.RANGE.name().toLowerCase());
549 matchRangeNode.put(CriterionCodec.PI_MATCH_HIGH_VALUE,
550 HexString.toHexString(rangeFieldMatch.highValue().asArray(),
551 null));
552 matchRangeNode.put(CriterionCodec.PI_MATCH_LOW_VALUE,
553 HexString.toHexString(rangeFieldMatch.lowValue().asArray(),
554 null));
555
556 return matchRangeNode;
557 }
558
Daniele Moroc6f2f7f2020-12-18 10:55:57 +0100559 private ObjectNode parsePiMatchOptional(PiOptionalFieldMatch optionalFieldMatch) {
560
561 ObjectNode optionalExactNode = context.mapper().createObjectNode();
562 optionalExactNode.put(CriterionCodec.PI_MATCH_FIELD_ID, optionalFieldMatch.fieldId().id());
563 optionalExactNode.put(CriterionCodec.PI_MATCH_TYPE, PiMatchType.OPTIONAL.name().toLowerCase());
564 optionalExactNode.put(CriterionCodec.PI_MATCH_VALUE,
565 HexString.toHexString(optionalFieldMatch.value().asArray(),
566 null));
567 return optionalExactNode;
568 }
569
Frank Wang74ce2c12018-04-11 20:26:45 +0800570 private class FormatProtocolIndependent implements CriterionTypeFormatter {
571 @Override
572 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
573 final PiCriterion piCriterion = (PiCriterion) criterion;
574 ArrayNode matchNodes = context.mapper().createArrayNode();
575 for (PiFieldMatch fieldMatch : piCriterion.fieldMatches()) {
576 switch (fieldMatch.type()) {
577 case EXACT:
578 matchNodes.add(parsePiMatchExact((PiExactFieldMatch) fieldMatch));
579 break;
580 case LPM:
581 matchNodes.add(parsePiMatchLpm((PiLpmFieldMatch) fieldMatch));
582 break;
583 case TERNARY:
584 matchNodes.add(parsePiMatchTernary((PiTernaryFieldMatch) fieldMatch));
585 break;
586 case RANGE:
Frank Wang74ce2c12018-04-11 20:26:45 +0800587 matchNodes.add(parsePiMatchRange((PiRangeFieldMatch) fieldMatch));
588 break;
Daniele Moroc6f2f7f2020-12-18 10:55:57 +0100589 case OPTIONAL:
590 matchNodes.add(parsePiMatchOptional((PiOptionalFieldMatch) fieldMatch));
591 break;
Frank Wang74ce2c12018-04-11 20:26:45 +0800592 default:
593 throw new IllegalArgumentException("Type " + fieldMatch.type().name() + " is unsupported");
594 }
595 }
596 return (ObjectNode) root.set(CriterionCodec.PI_MATCHES, matchNodes);
597 }
598 }
599
Seyeon Jeong8d3cad22020-02-28 01:17:34 -0800600 private class FormatExtension implements CriterionTypeFormatter {
601 @Override
602 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
603 Output output = new Output(new ByteArrayOutputStream());
604 KryoNamespaces.API.borrow().writeObject(output, criterion);
605 root.put(CriterionCodec.EXTENSION, output.toBytes());
606 output.flush();
607 output.close();
608
609 return root;
610 }
611 }
612
Ray Milkeyd43fe452015-05-29 09:35:12 -0700613 private class FormatDummyType implements CriterionTypeFormatter {
614
615 @Override
616 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
617 checkNotNull(criterion, "Criterion cannot be null");
618
619 return root.put(CriterionCodec.TYPE, criterion.type().toString());
620
621 }
622 }
623
624 /**
625 * Encodes a criterion into a JSON node.
626 *
627 * @return encoded JSON object for the given criterion
628 */
629 public ObjectNode encode() {
630 final ObjectNode result = context.mapper().createObjectNode()
631 .put(CriterionCodec.TYPE, criterion.type().toString());
632
633 CriterionTypeFormatter formatter =
634 checkNotNull(
635 formatMap.get(criterion.type()),
636 "No formatter found for criterion type "
637 + criterion.type().toString());
638
639 return formatter.encodeCriterion(result, criterion);
640 }
641
642}