import java.math.BigInteger;
import java.util.StringTokenizer;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
+import org.opendaylight.openflowplugin.openflow.md.util.OpenflowPortsUtil;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpVersion;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
private static final Logger LOG = LoggerFactory.getLogger(HashUtil.class);
private static final int BASE_16 = 16;
private static final int BASE_10 = 10;
+ private static final long IPV6_TOKENS_COUNT = 8;
+ public static final String IPV6_TOKEN = ":0000";
private HashUtil() {
throw new IllegalStateException("This class should not be instantiated.");
}
- public static int calculateEthernetMatchHash(EthernetMatch ethernetMatch) {
- int hash = 0;
+ public static long calculateEthernetMatchHash(EthernetMatch ethernetMatch) {
+ long hash = 0;
EthernetType ethernetType = ethernetMatch.getEthernetType();
if (null != ethernetType) {
return hash;
}
- public static int calculateEthenetSourceHash(EthernetSource ethernetSource) {
- int hash = calculateMacAddressHash(ethernetSource.getAddress());
+ public static long calculateEthenetSourceHash(EthernetSource ethernetSource) {
+ long hash = calculateMacAddressHash(ethernetSource.getAddress());
hash += calculateMacAddressHash(ethernetSource.getMask());
return hash;
}
- public static int calculateEthernetDestinationHash(EthernetDestination ethernetDestination) {
- int hash = calculateMacAddressHash(ethernetDestination.getAddress());
+ public static long calculateEthernetDestinationHash(EthernetDestination ethernetDestination) {
+ long hash = calculateMacAddressHash(ethernetDestination.getAddress());
hash += calculateMacAddressHash(ethernetDestination.getMask());
return hash;
}
- public static int calculateMacAddressHash(MacAddress macAddress) {
+ public static long calculateMacAddressHash(MacAddress macAddress) {
- int hash = 0;
+ long hash = 0;
if (null != macAddress) {
StringTokenizer stringTokenizer = new StringTokenizer(macAddress.getValue(), ":");
- hash = parseTokens(stringTokenizer, BASE_16);
+ hash = parseTokens(stringTokenizer, BASE_16, 8);
}
- LOG.trace("Calculated hash {} for mac {}", hash, macAddress);
return hash;
}
- public static int calculateMatchHash(final Match match) {
- int hash = 0;
- int subHash = 0;
- int base = 0;
+ public static long calculateMatchHash(final Match match, short version) {
+ long hash = 0;
+ long subHash = 0;
+ long base = 0;
if (null != match) {
if (null != match.getEthernetMatch()) {
hash = 1 << base;
base++;
if (null != match.getInPhyPort()) {
hash = 1 << base;
- subHash += calculateNodeConnectorIdHash(match.getInPhyPort());
+ subHash += calculateNodeConnectorIdHash(match.getInPhyPort(), version);
}
base++;
if (null != match.getInPort()) {
hash = 1 << base;
- subHash += calculateNodeConnectorIdHash(match.getInPort());
+ subHash += calculateNodeConnectorIdHash(match.getInPort(), version);
}
base++;
if (null != match.getIpMatch()) {
return hash + subHash;
}
- private static int calculateTunnelHash(final Tunnel tunnel) {
- int hash = 0;
+ private static long calculateTunnelHash(final Tunnel tunnel) {
+ long hash = 0;
BigInteger tunnelId = tunnel.getTunnelId();
if (null != tunnelId) {
hash += tunnelId.intValue();
return hash;
}
- private static int calculateVlanMatchHash(final VlanMatch vlanMatch) {
- int hash = 0;
+ private static long calculateVlanMatchHash(final VlanMatch vlanMatch) {
+ long hash = 0;
VlanId vlanId = vlanMatch.getVlanId();
if (null != vlanId) {
return hash;
}
- private static int calculateTcpFlagMatch(final TcpFlagMatch tcpFlagMatch) {
- int hash = tcpFlagMatch.getTcpFlag().intValue();
+ private static long calculateTcpFlagMatch(final TcpFlagMatch tcpFlagMatch) {
+ long hash = tcpFlagMatch.getTcpFlag().intValue();
return hash;
}
- private static int calculateProtocolMatchFieldsHash(final ProtocolMatchFields protocolMatchFields) {
- int hash = 0;
+ private static long calculateProtocolMatchFieldsHash(final ProtocolMatchFields protocolMatchFields) {
+ long hash = 0;
Short mplsBos = protocolMatchFields.getMplsBos();
if (null != mplsBos) {
hash += mplsBos.intValue();
return hash;
}
- private static int calculateMetadataHash(final Metadata metadata) {
- int hash = metadata.getMetadata().intValue();
- hash += metadata.getMetadataMask().intValue();
+ private static long calculateMetadataHash(final Metadata metadata) {
+ long hash = metadata.getMetadata().intValue();
+ if (null != metadata.getMetadataMask()) {
+ hash += metadata.getMetadataMask().intValue();
+ }
return hash;
}
- private static int calculateIcmpv6MatchHash(final Icmpv6Match icmpv6Match) {
- int hash = icmpv6Match.getIcmpv6Code().intValue();
+ private static long calculateIcmpv6MatchHash(final Icmpv6Match icmpv6Match) {
+ long hash = icmpv6Match.getIcmpv6Code().intValue();
hash += icmpv6Match.getIcmpv6Type().intValue();
return hash;
}
- private static int calculateLayer4MatchHash(final Layer4Match layer4Match) {
- int hash = 0;
+ private static long calculateLayer4MatchHash(final Layer4Match layer4Match) {
+ long hash = 0;
if (layer4Match instanceof SctpMatch) {
hash += calculateSctpMatchHash((SctpMatch) layer4Match);
}
return hash;
}
- private static int calculateUdpMatchHash(final UdpMatch layer4Match) {
- int hash = 0;
+ private static long calculateUdpMatchHash(final UdpMatch layer4Match) {
+ long hash = 0;
return hash;
}
- private static int calculateTcpMatchHash(final TcpMatch layer4Match) {
- int hash = 0;
+ private static long calculateTcpMatchHash(final TcpMatch layer4Match) {
+ long hash = 0;
PortNumber sourcePort = layer4Match.getTcpSourcePort();
if (null != sourcePort) {
hash += sourcePort.getValue().intValue();
return hash;
}
- private static int calculateSctpMatchHash(final SctpMatch layer4Match) {
- int hash = 0;
+ private static long calculateSctpMatchHash(final SctpMatch layer4Match) {
+ long hash = 0;
PortNumber portNumber = layer4Match.getSctpDestinationPort();
if (null != portNumber) {
return hash;
}
- private static int calculateLayer3MatchHash(final Layer3Match layer3Match) {
- int hash = 0;
+ private static long calculateLayer3MatchHash(final Layer3Match layer3Match) {
+ long hash = 0;
if (layer3Match instanceof ArpMatch) {
hash += calculateArpMatchHash((ArpMatch) layer3Match);
}
return hash;
}
- private static int calculateTunnelIpv4Hash(final TunnelIpv4Match layer3Match) {
+ private static long calculateTunnelIpv4Hash(final TunnelIpv4Match layer3Match) {
Ipv4Prefix tunnelIpv4Destination = layer3Match.getTunnelIpv4Destination();
- int hash = calculateIpv4PrefixHash(tunnelIpv4Destination);
+ long hash = calculateIpv4PrefixHash(tunnelIpv4Destination);
Ipv4Prefix tunnelIpv4Source = layer3Match.getTunnelIpv4Source();
hash += calculateIpv4PrefixHash(tunnelIpv4Source);
return hash;
}
- private static int calculateIpv6MatchHash(final Ipv6Match layer3Match) {
- int hash = 0;
+ private static long calculateIpv6MatchHash(final Ipv6Match layer3Match) {
+ long hash = 0;
Ipv6Prefix ipv6Destination = layer3Match.getIpv6Destination();
if (null != ipv6Destination) {
hash += calculateIpv6PrefixHash(ipv6Destination);
}
+
+ if (null != layer3Match.getIpv6Source()) {
+ hash += calculateIpv6PrefixHash(layer3Match.getIpv6Source());
+ }
+
+ if (null != layer3Match.getIpv6ExtHeader()) {
+ hash += layer3Match.getIpv6ExtHeader().getIpv6Exthdr();
+ hash += layer3Match.getIpv6ExtHeader().getIpv6ExthdrMask();
+ }
+
+ if (null != layer3Match.getIpv6NdSll()) {
+ hash += calculateMacAddressHash(layer3Match.getIpv6NdSll());
+ }
+ if (null != layer3Match.getIpv6NdTll()) {
+ hash += calculateMacAddressHash(layer3Match.getIpv6NdTll());
+ }
+ if (null != layer3Match.getIpv6NdTarget()) {
+ hash += calculateIpv6AddressHash(layer3Match.getIpv6NdTarget());
+ }
return hash;
}
- public static int calculateIpv6PrefixHash(final Ipv6Prefix ipv6Prefix) {
- StringTokenizer stringTokenizer = new StringTokenizer(ipv6Prefix.getValue(), ":");
- int hash = parseTokens(stringTokenizer, BASE_16);
+ public static long calculateIpv6PrefixHash(final Ipv6Prefix ipv6Prefix) {
+
+ StringTokenizer stringTokenizer = getStringTokenizerWithFullAddressString(ipv6Prefix.getValue());
+
+ long hash = parseTokens(stringTokenizer, BASE_16, 16);
return hash;
}
- private static int parseTokens(final StringTokenizer stringTokenizer, int base) {
- return parseTokens(stringTokenizer, 0, base);
+ public static long calculateIpv6AddressHash(final Ipv6Address ipv6Address) {
+
+ StringTokenizer stringTokenizer = getStringTokenizerWithFullAddressString(ipv6Address.getValue());
+
+ long hash = parseTokens(stringTokenizer, BASE_16, 16);
+ return hash;
}
- private static int parseTokens(final StringTokenizer stringTokenizer, int stopper, int base) {
- int hash = 0;
+ private static StringTokenizer getStringTokenizerWithFullAddressString(String value) {
+ String ipv6Value = value.replace("::", ":0000:");
+ StringTokenizer stringTokenizer = new StringTokenizer(ipv6Value, ":");
+
+ long delta = IPV6_TOKENS_COUNT - stringTokenizer.countTokens();
+
+ StringBuffer additions = new StringBuffer();
+
+ if (delta > 0) {
+ while (delta > 0) {
+ additions.append(IPV6_TOKEN);
+ delta--;
+ }
+ if (ipv6Value.contains("/")) {
+ ipv6Value = ipv6Value.replace("/", additions.toString() + "/");
+ } else {
+ ipv6Value += additions.toString();
+ }
+ stringTokenizer = new StringTokenizer(ipv6Value, ":");
+ }
+ return stringTokenizer;
+ }
+
+ private static long calculateStopperBasedOnMaskValue(final Ipv6Prefix ipv6Prefix, long bitsBase) {
+ double maskValue = extractMask(ipv6Prefix);
+ double bitCount = maskValue / bitsBase;
+ return (int) Math.ceil(bitCount);
+ }
+
+ private static long extractMask(final Ipv6Prefix ipv6Prefix) {
+ StringTokenizer maskTokenizer = new StringTokenizer(ipv6Prefix.getValue(), "/");
+ long mask = 0;
+ if (maskTokenizer.countTokens() > 1) {
+ maskTokenizer.nextToken();
+ mask = Integer.parseInt(maskTokenizer.nextToken());
+ }
+ return mask;
+ }
+
+ private static long parseTokens(final StringTokenizer stringTokenizer, int base, int bitShift) {
+ return parseTokens(stringTokenizer, 0, base, bitShift);
+ }
+
+ private static long parseTokens(final StringTokenizer stringTokenizer, long stopper, int base, int bitShift) {
+ long hash = 0;
if (stringTokenizer.countTokens() > 0) {
- int step = 0;
+ long step = 0;
while (stringTokenizer.hasMoreTokens()) {
+ String token = stringTokenizer.nextToken();
step++;
- try {
- hash = hash ^ ((Integer.parseInt(stringTokenizer.nextToken(), base) * step) + step);
- } catch (NumberFormatException nfe) {
- LOG.trace("Skipping empty token.");
+
+ if (token.equals("")) {
+ token = "0";
}
- if (stopper > 0 && step == stopper) {
- break;
+
+ if (token.contains("/")) {
+ StringTokenizer tokenizer = new StringTokenizer(token, "/");
+ hash += parseTokens(tokenizer, stopper, base, bitShift);
+ } else {
+ hash += Long.parseLong(token, base) << (bitShift * step);
+ if (stopper > 0 && step == stopper) {
+ break;
+ }
}
}
}
return hash;
}
- private static int calculateIpv4MatchHash(final Ipv4Match layer3Match) {
- int hash = 0;
+ private static long calculateIpv4MatchHash(final Ipv4Match layer3Match) {
+ long hash = 0;
Ipv4Prefix ipv4Destination = layer3Match.getIpv4Destination();
if (null != ipv4Destination) {
hash += calculateIpv4PrefixHash(ipv4Destination);
return hash;
}
- private static int calculateArpMatchHash(final ArpMatch layer3Match) {
- int hash = 0;
+ private static long calculateArpMatchHash(final ArpMatch layer3Match) {
+ long hash = 0;
Integer arpOp = layer3Match.getArpOp();
if (null != arpOp) {
hash += arpOp.intValue();
return hash;
}
- public static int calculateIpv4PrefixHash(final Ipv4Prefix ipv4Prefix) {
- int hash = 0;
+ public static long calculateIpv4PrefixHash(final Ipv4Prefix ipv4Prefix) {
+ long hash = 0;
StringTokenizer prefixAsArray = new StringTokenizer(ipv4Prefix.getValue(), "/");
if (prefixAsArray.countTokens() == 2) {
String address = prefixAsArray.nextToken();
- Integer mask = Integer.parseInt(prefixAsArray.nextToken());
- int numberOfAddressPartsToUse = (int) Math.ceil(mask.doubleValue() / 8);
+ Long mask = Long.parseLong(prefixAsArray.nextToken());
+ long numberOfAddressPartsToUse = (int) Math.ceil(mask.doubleValue() / 8);
hash += calculateIpAdressHash(address, numberOfAddressPartsToUse, BASE_10);
hash += mask.shortValue();
}
}
- private static int calculateIpAdressHash(final String address, int numberOfParts, int base) {
+ private static long calculateIpAdressHash(final String address, long numberOfParts, int base) {
StringTokenizer stringTokenizer = new StringTokenizer(address, ".");
- int hash = parseTokens(stringTokenizer, numberOfParts, base);
+ long hash = parseTokens(stringTokenizer, numberOfParts, base, 8);
return hash;
}
- private static int calculateIpMatchHash(final IpMatch ipMatch) {
- int hash = 0;
+ private static long calculateIpMatchHash(final IpMatch ipMatch) {
+ long hash = 0;
Short ipEcn = ipMatch.getIpEcn();
if (null != ipEcn) {
hash += ipEcn.shortValue();
return hash;
}
- private static int calculateNodeConnectorIdHash(final NodeConnectorId inPhyPort) {
- int hash = 0;
- hash += Integer.valueOf(inPhyPort.getValue());
+ private static long calculateNodeConnectorIdHash(final NodeConnectorId inPhyPort, short version) {
+ long hash = 0;
+ Long portFromLogicalName = OpenflowPortsUtil.getPortFromLogicalName(OpenflowVersion.get(version), inPhyPort.getValue());
+ hash += portFromLogicalName.intValue();
return hash;
}
- private static int calculateIcmpV6MatchHash(final Icmpv6Match icmpv6Match) {
- int hash = 0;
+ private static long calculateIcmpV6MatchHash(final Icmpv6Match icmpv6Match) {
+ long hash = 0;
if (null != icmpv6Match.getIcmpv6Code()) {
hash += icmpv6Match.getIcmpv6Code();
}
return hash;
}
- public static int calculateIcmpV4MatchHash(final Icmpv4Match icmpv4Match) {
- int hash = 0;
+ public static long calculateIcmpV4MatchHash(final Icmpv4Match icmpv4Match) {
+ long hash = 0;
if (null != icmpv4Match.getIcmpv4Code()) {
hash += icmpv4Match.getIcmpv4Code();
}