FlowHash computation enhanced
[openflowplugin.git] / openflowplugin-impl / src / main / java / org / opendaylight / openflowplugin / impl / util / HashUtil.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.openflowplugin.impl.util;
10
11 import java.math.BigInteger;
12 import java.util.StringTokenizer;
13 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
14 import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
15 import org.opendaylight.openflowplugin.openflow.md.util.OpenflowPortsUtil;
16 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpVersion;
17 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanPcp;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpSourceHardwareAddress;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpTargetHardwareAddress;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetDestination;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetSource;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetType;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatch;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Icmpv4Match;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Icmpv6Match;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatch;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer3Match;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer4Match;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Metadata;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.ProtocolMatchFields;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.TcpFlagMatch;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Tunnel;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatch;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatch;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4Match;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6Match;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.TunnelIpv4Match;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.SctpMatch;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatch;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatch;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.protocol.match.fields.Pbb;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanId;
50 import org.slf4j.Logger;
51 import org.slf4j.LoggerFactory;
52
53 /**
54  * Created by Martin Bobak <mbobak@cisco.com> on 8.4.2015.
55  */
56 public final class HashUtil {
57
58     private static final Logger LOG = LoggerFactory.getLogger(HashUtil.class);
59     private static final int BASE_16 = 16;
60     private static final int BASE_10 = 10;
61     private static final long IPV6_TOKENS_COUNT = 8;
62     public static final String IPV6_TOKEN = ":0000";
63
64     private HashUtil() {
65
66         throw new IllegalStateException("This class should not be instantiated.");
67     }
68
69     public static long calculateEthernetMatchHash(EthernetMatch ethernetMatch) {
70         long hash = 0;
71
72         EthernetType ethernetType = ethernetMatch.getEthernetType();
73         if (null != ethernetType) {
74             hash += ethernetType.getType().getValue();
75         }
76
77         EthernetDestination ethernetDestination = ethernetMatch.getEthernetDestination();
78         if (null != ethernetDestination) {
79             hash += calculateEthernetDestinationHash(ethernetDestination);
80         }
81
82         EthernetSource ethernetSource = ethernetMatch.getEthernetSource();
83         if (null != ethernetSource) {
84             hash += calculateEthenetSourceHash(ethernetSource);
85         }
86
87         return hash;
88     }
89
90     public static long calculateEthenetSourceHash(EthernetSource ethernetSource) {
91         long hash = calculateMacAddressHash(ethernetSource.getAddress());
92         hash += calculateMacAddressHash(ethernetSource.getMask());
93         return hash;
94     }
95
96     public static long calculateEthernetDestinationHash(EthernetDestination ethernetDestination) {
97         long hash = calculateMacAddressHash(ethernetDestination.getAddress());
98         hash += calculateMacAddressHash(ethernetDestination.getMask());
99         return hash;
100     }
101
102     public static long calculateMacAddressHash(MacAddress macAddress) {
103
104         long hash = 0;
105         if (null != macAddress) {
106             StringTokenizer stringTokenizer = new StringTokenizer(macAddress.getValue(), ":");
107             hash = parseTokens(stringTokenizer, BASE_16, 8);
108         }
109         return hash;
110     }
111
112     public static long calculateMatchHash(final Match match, DeviceContext deviceContext) {
113         long hash = 0;
114         long subHash = 0;
115         long base = 0;
116         if (null != match) {
117             if (null != match.getEthernetMatch()) {
118                 hash = 1 << base;
119                 subHash += calculateEthernetMatchHash(match.getEthernetMatch());
120             }
121             base++;
122             if (null != match.getIcmpv4Match()) {
123                 hash = 1 << base;
124                 subHash += calculateIcmpV4MatchHash(match.getIcmpv4Match());
125             }
126             base++;
127             if (null != match.getIcmpv6Match()) {
128                 hash = 1 << base;
129                 subHash += calculateIcmpV6MatchHash(match.getIcmpv6Match());
130             }
131             base++;
132             if (null != match.getInPhyPort()) {
133                 hash = 1 << base;
134                 subHash += calculateNodeConnectorIdHash(match.getInPhyPort(), deviceContext);
135             }
136             base++;
137             if (null != match.getInPort()) {
138                 hash = 1 << base;
139                 subHash += calculateNodeConnectorIdHash(match.getInPort(), deviceContext);
140             }
141             base++;
142             if (null != match.getIpMatch()) {
143                 hash = 1 << base;
144                 subHash += calculateIpMatchHash(match.getIpMatch());
145             }
146             base++;
147             if (null != match.getLayer3Match()) {
148                 hash = 1 << base;
149                 subHash += calculateLayer3MatchHash(match.getLayer3Match());
150             }
151             base++;
152             if (null != match.getLayer4Match()) {
153                 hash = 1 << base;
154                 subHash += calculateLayer4MatchHash(match.getLayer4Match());
155             }
156             base++;
157             if (null != match.getIcmpv6Match()) {
158                 hash = 1 << base;
159                 subHash += calculateIcmpv6MatchHash(match.getIcmpv6Match());
160             }
161             base++;
162             if (null != match.getMetadata()) {
163                 hash = 1 << base;
164                 subHash += calculateMetadataHash(match.getMetadata());
165             }
166             base++;
167             if (null != match.getProtocolMatchFields()) {
168                 hash = 1 << base;
169                 subHash += calculateProtocolMatchFieldsHash(match.getProtocolMatchFields());
170             }
171             base++;
172             if (null != match.getTcpFlagMatch()) {
173                 hash = 1 << base;
174                 subHash += calculateTcpFlagMatch(match.getTcpFlagMatch());
175             }
176             base++;
177             if (null != match.getVlanMatch()) {
178                 hash = 1 << base;
179                 subHash += calculateVlanMatchHash(match.getVlanMatch());
180             }
181             base++;
182             if (null != match.getTunnel()) {
183                 hash = 1 << base;
184                 subHash += calculateTunnelHash(match.getTunnel());
185             }
186         }
187         return hash + subHash;
188     }
189
190     private static long calculateTunnelHash(final Tunnel tunnel) {
191         long hash = 0;
192         BigInteger tunnelId = tunnel.getTunnelId();
193         if (null != tunnelId) {
194             hash += tunnelId.intValue();
195         }
196
197         BigInteger tunnelMask = tunnel.getTunnelMask();
198         if (null != tunnelMask) {
199             hash += tunnelMask.intValue();
200         }
201         return hash;
202     }
203
204     private static long calculateVlanMatchHash(final VlanMatch vlanMatch) {
205         long hash = 0;
206
207         VlanId vlanId = vlanMatch.getVlanId();
208         if (null != vlanId) {
209             hash += vlanId.getVlanId().getValue().intValue();
210         }
211
212         VlanPcp vlanPcp = vlanMatch.getVlanPcp();
213         if (null != vlanPcp) {
214             hash += vlanPcp.getValue().shortValue();
215         }
216
217         return hash;
218     }
219
220     private static long calculateTcpFlagMatch(final TcpFlagMatch tcpFlagMatch) {
221         long hash = tcpFlagMatch.getTcpFlag().intValue();
222         return hash;
223     }
224
225     private static long calculateProtocolMatchFieldsHash(final ProtocolMatchFields protocolMatchFields) {
226         long hash = 0;
227         Short mplsBos = protocolMatchFields.getMplsBos();
228         if (null != mplsBos) {
229             hash += mplsBos.intValue();
230         }
231         Short mplsTc = protocolMatchFields.getMplsTc();
232         if (null != mplsTc) {
233             hash += mplsTc.intValue();
234         }
235         Pbb pbb = protocolMatchFields.getPbb();
236         if (null != pbb) {
237             if (null != pbb.getPbbIsid()) {
238                 hash += pbb.getPbbIsid().intValue();
239             }
240             if (null != pbb.getPbbMask()) {
241                 hash += pbb.getPbbMask().intValue();
242             }
243         }
244         Long mplsLabel = protocolMatchFields.getMplsLabel();
245         if (null != mplsLabel) {
246             hash += mplsLabel.intValue();
247         }
248         return hash;
249     }
250
251     private static long calculateMetadataHash(final Metadata metadata) {
252         long hash = metadata.getMetadata().intValue();
253         if (null != metadata.getMetadataMask()) {
254             hash += metadata.getMetadataMask().intValue();
255         }
256         return hash;
257     }
258
259     private static long calculateIcmpv6MatchHash(final Icmpv6Match icmpv6Match) {
260         long hash = icmpv6Match.getIcmpv6Code().intValue();
261         hash += icmpv6Match.getIcmpv6Type().intValue();
262         return hash;
263     }
264
265     private static long calculateLayer4MatchHash(final Layer4Match layer4Match) {
266         long hash = 0;
267         if (layer4Match instanceof SctpMatch) {
268             hash += calculateSctpMatchHash((SctpMatch) layer4Match);
269         }
270
271         if (layer4Match instanceof TcpMatch) {
272             hash += calculateTcpMatchHash((TcpMatch) layer4Match);
273         }
274         if (layer4Match instanceof UdpMatch) {
275             hash += calculateUdpMatchHash((UdpMatch) layer4Match);
276         }
277         return hash;
278     }
279
280     private static long calculateUdpMatchHash(final UdpMatch layer4Match) {
281         long hash = 0;
282         return hash;
283     }
284
285     private static long calculateTcpMatchHash(final TcpMatch layer4Match) {
286         long hash = 0;
287         PortNumber sourcePort = layer4Match.getTcpSourcePort();
288         if (null != sourcePort) {
289             hash += sourcePort.getValue().intValue();
290         }
291
292         PortNumber destinationPort = layer4Match.getTcpDestinationPort();
293         if (null != destinationPort) {
294             hash += destinationPort.getValue().intValue();
295         }
296         return hash;
297     }
298
299     private static long calculateSctpMatchHash(final SctpMatch layer4Match) {
300         long hash = 0;
301
302         PortNumber portNumber = layer4Match.getSctpDestinationPort();
303         if (null != portNumber) {
304             hash += portNumber.getValue().intValue();
305         }
306
307         PortNumber sourcePort = layer4Match.getSctpSourcePort();
308         if (null != sourcePort) {
309             hash += sourcePort.getValue().intValue();
310         }
311         return hash;
312     }
313
314     private static long calculateLayer3MatchHash(final Layer3Match layer3Match) {
315         long hash = 0;
316         if (layer3Match instanceof ArpMatch) {
317             hash += calculateArpMatchHash((ArpMatch) layer3Match);
318         }
319         if (layer3Match instanceof Ipv4Match) {
320             hash += calculateIpv4MatchHash((Ipv4Match) layer3Match);
321         }
322         if (layer3Match instanceof Ipv6Match) {
323             hash += calculateIpv6MatchHash((Ipv6Match) layer3Match);
324
325         }
326         if (layer3Match instanceof TunnelIpv4Match) {
327             hash += calculateTunnelIpv4Hash((TunnelIpv4Match) layer3Match);
328         }
329         return hash;
330     }
331
332     private static long calculateTunnelIpv4Hash(final TunnelIpv4Match layer3Match) {
333         Ipv4Prefix tunnelIpv4Destination = layer3Match.getTunnelIpv4Destination();
334         long hash = calculateIpv4PrefixHash(tunnelIpv4Destination);
335         Ipv4Prefix tunnelIpv4Source = layer3Match.getTunnelIpv4Source();
336         hash += calculateIpv4PrefixHash(tunnelIpv4Source);
337         return hash;
338     }
339
340     private static long calculateIpv6MatchHash(final Ipv6Match layer3Match) {
341         long hash = 0;
342         Ipv6Prefix ipv6Destination = layer3Match.getIpv6Destination();
343         if (null != ipv6Destination) {
344             hash += calculateIpv6PrefixHash(ipv6Destination);
345         }
346
347         if (null != layer3Match.getIpv6Source()) {
348             hash += calculateIpv6PrefixHash(layer3Match.getIpv6Source());
349         }
350
351         if (null != layer3Match.getIpv6ExtHeader()) {
352             hash += layer3Match.getIpv6ExtHeader().getIpv6Exthdr();
353             hash += layer3Match.getIpv6ExtHeader().getIpv6ExthdrMask();
354         }
355
356         if (null != layer3Match.getIpv6NdSll()) {
357             hash += calculateMacAddressHash(layer3Match.getIpv6NdSll());
358         }
359         if (null != layer3Match.getIpv6NdTll()) {
360             hash += calculateMacAddressHash(layer3Match.getIpv6NdTll());
361         }
362         if (null != layer3Match.getIpv6NdTarget()) {
363             hash += calculateIpv6AddressHash(layer3Match.getIpv6NdTarget());
364         }
365         return hash;
366     }
367
368
369     public static long calculateIpv6PrefixHash(final Ipv6Prefix ipv6Prefix) {
370
371         StringTokenizer stringTokenizer = getStringTokenizerWithFullAddressString(ipv6Prefix.getValue());
372
373         long hash = parseTokens(stringTokenizer, BASE_16, 16);
374         return hash;
375     }
376
377     public static long calculateIpv6AddressHash(final Ipv6Address ipv6Address) {
378
379         StringTokenizer stringTokenizer = getStringTokenizerWithFullAddressString(ipv6Address.getValue());
380
381         long hash = parseTokens(stringTokenizer, BASE_16, 16);
382         return hash;
383     }
384
385     private static StringTokenizer getStringTokenizerWithFullAddressString(String value) {
386         String ipv6Value = value.replace("::", ":0000:");
387         StringTokenizer stringTokenizer = new StringTokenizer(ipv6Value, ":");
388
389         long delta = IPV6_TOKENS_COUNT - stringTokenizer.countTokens();
390
391         StringBuffer additions = new StringBuffer();
392
393         if (delta > 0) {
394             while (delta > 0) {
395                 additions.append(IPV6_TOKEN);
396                 delta--;
397             }
398             if (ipv6Value.contains("/")) {
399                 ipv6Value = ipv6Value.replace("/", additions.toString() + "/");
400             } else {
401                 ipv6Value += additions.toString();
402             }
403             stringTokenizer = new StringTokenizer(ipv6Value, ":");
404         }
405         return stringTokenizer;
406     }
407
408     private static long calculateStopperBasedOnMaskValue(final Ipv6Prefix ipv6Prefix, long bitsBase) {
409         double maskValue = extractMask(ipv6Prefix);
410         double bitCount = maskValue / bitsBase;
411         return (int) Math.ceil(bitCount);
412     }
413
414     private static long extractMask(final Ipv6Prefix ipv6Prefix) {
415         StringTokenizer maskTokenizer = new StringTokenizer(ipv6Prefix.getValue(), "/");
416         long mask = 0;
417         if (maskTokenizer.countTokens() > 1) {
418             maskTokenizer.nextToken();
419             mask = Integer.parseInt(maskTokenizer.nextToken());
420         }
421         return mask;
422     }
423
424     private static long parseTokens(final StringTokenizer stringTokenizer, int base, int bitShift) {
425         return parseTokens(stringTokenizer, 0, base, bitShift);
426     }
427
428     private static long parseTokens(final StringTokenizer stringTokenizer, long stopper, int base, int bitShift) {
429         long hash = 0;
430         if (stringTokenizer.countTokens() > 0) {
431             long step = 0;
432             while (stringTokenizer.hasMoreTokens()) {
433                 String token = stringTokenizer.nextToken();
434                 step++;
435
436                 if (token.equals("")) {
437                     token = "0";
438                 }
439
440                 if (token.contains("/")) {
441                     StringTokenizer tokenizer = new StringTokenizer(token, "/");
442                     hash += parseTokens(tokenizer, stopper, base, bitShift);
443                 } else {
444                     hash += Long.parseLong(token, base) << (bitShift * step);
445                     if (stopper > 0 && step == stopper) {
446                         break;
447                     }
448                 }
449             }
450         }
451         return hash;
452     }
453
454     private static long calculateIpv4MatchHash(final Ipv4Match layer3Match) {
455         long hash = 0;
456         Ipv4Prefix ipv4Destination = layer3Match.getIpv4Destination();
457         if (null != ipv4Destination) {
458             hash += calculateIpv4PrefixHash(ipv4Destination);
459         }
460
461         Ipv4Prefix ipv4Source = layer3Match.getIpv4Source();
462
463         if (null != ipv4Source) {
464             hash += calculateIpv4PrefixHash(ipv4Source);
465         }
466
467         //TODO : add calculation of hashes for augmentations
468         return hash;
469     }
470
471     private static long calculateArpMatchHash(final ArpMatch layer3Match) {
472         long hash = 0;
473         Integer arpOp = layer3Match.getArpOp();
474         if (null != arpOp) {
475             hash += arpOp.intValue();
476         }
477         ArpSourceHardwareAddress arpSourceHardwareAddress = layer3Match.getArpSourceHardwareAddress();
478         if (null != arpSourceHardwareAddress) {
479             hash += calculateMacAddressHash(arpSourceHardwareAddress.getAddress());
480             hash += calculateMacAddressHash(arpSourceHardwareAddress.getMask());
481         }
482
483         Ipv4Prefix sourceTransportAddress = layer3Match.getArpSourceTransportAddress();
484         if (null != sourceTransportAddress) {
485             hash += calculateIpv4PrefixHash(sourceTransportAddress);
486         }
487
488         ArpTargetHardwareAddress arpTargetHardwareAddress = layer3Match.getArpTargetHardwareAddress();
489         if (null != arpTargetHardwareAddress) {
490             hash += calculateMacAddressHash(arpTargetHardwareAddress.getAddress());
491             hash += calculateMacAddressHash(arpTargetHardwareAddress.getMask());
492         }
493
494         Ipv4Prefix targetTransportAddress = layer3Match.getArpTargetTransportAddress();
495         if (null != targetTransportAddress) {
496             hash += calculateIpv4PrefixHash(targetTransportAddress);
497         }
498
499         return hash;
500     }
501
502     public static long calculateIpv4PrefixHash(final Ipv4Prefix ipv4Prefix) {
503         long hash = 0;
504         StringTokenizer prefixAsArray = new StringTokenizer(ipv4Prefix.getValue(), "/");
505         if (prefixAsArray.countTokens() == 2) {
506             String address = prefixAsArray.nextToken();
507             Long mask = Long.parseLong(prefixAsArray.nextToken());
508             long numberOfAddressPartsToUse = (int) Math.ceil(mask.doubleValue() / 8);
509             hash += calculateIpAdressHash(address, numberOfAddressPartsToUse, BASE_10);
510             hash += mask.shortValue();
511         }
512         return hash;
513     }
514
515
516     private static long calculateIpAdressHash(final String address, long numberOfParts, int base) {
517         StringTokenizer stringTokenizer = new StringTokenizer(address, ".");
518         long hash = parseTokens(stringTokenizer, numberOfParts, base, 8);
519         return hash;
520     }
521
522     private static long calculateIpMatchHash(final IpMatch ipMatch) {
523         long hash = 0;
524         Short ipEcn = ipMatch.getIpEcn();
525         if (null != ipEcn) {
526             hash += ipEcn.shortValue();
527         }
528         Short ipProtocol = ipMatch.getIpProtocol();
529         if (null != ipProtocol) {
530             hash += ipProtocol;
531         }
532
533         Short ipDscp = ipMatch.getIpDscp().getValue();
534         if (null != ipDscp) {
535             hash += ipDscp;
536         }
537
538         IpVersion ipVersion = ipMatch.getIpProto();
539         if (null != ipVersion) {
540             hash += ipVersion.getIntValue();
541         }
542         return hash;
543     }
544
545     private static long calculateNodeConnectorIdHash(final NodeConnectorId inPhyPort, DeviceContext deviceContext) {
546         long hash = 0;
547         short version = deviceContext.getDeviceState().getVersion();
548         Long portFromLogicalName = OpenflowPortsUtil.getPortFromLogicalName(OpenflowVersion.get(version), inPhyPort.getValue());
549         hash += portFromLogicalName.intValue();
550         return hash;
551     }
552
553     private static long calculateIcmpV6MatchHash(final Icmpv6Match icmpv6Match) {
554         long hash = 0;
555         if (null != icmpv6Match.getIcmpv6Code()) {
556             hash += icmpv6Match.getIcmpv6Code();
557         }
558         if (null != icmpv6Match.getIcmpv6Type()) {
559             hash += icmpv6Match.getIcmpv6Type();
560         }
561         return hash;
562     }
563
564     public static long calculateIcmpV4MatchHash(final Icmpv4Match icmpv4Match) {
565         long hash = 0;
566         if (null != icmpv4Match.getIcmpv4Code()) {
567             hash += icmpv4Match.getIcmpv4Code();
568         }
569         if (null != icmpv4Match.getIcmpv4Type()) {
570             hash += icmpv4Match.getIcmpv4Type();
571         }
572         return hash;
573     }
574
575
576 }