X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;ds=sidebyside;f=openflowplugin%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fopenflowplugin%2Fopenflow%2Fmd%2Fcore%2Fsal%2Fconvertor%2FIpConversionUtil.java;h=5151d300c8ba8d8428e5fd8976810079af9e5a91;hb=e7a43b0114b91e623945b8c451de54dc867701cd;hp=912d22c9558ac9c5a8855bc4f5d63b3c4db810e2;hpb=bbf61eb21e7b639ad81faa33f80633a93d44abdd;p=openflowplugin.git diff --git a/openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/IpConversionUtil.java b/openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/IpConversionUtil.java index 912d22c955..5151d300c8 100644 --- a/openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/IpConversionUtil.java +++ b/openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/IpConversionUtil.java @@ -1,6 +1,5 @@ /* - * Copyright (c) 2015 Brocade, Communications Systems, Inc - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * Copyright (c) 2015 Cisco Systems, Inc., Brocade, Communications Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, @@ -9,34 +8,66 @@ package org.opendaylight.openflowplugin.openflow.md.core.sal.convertor; -import com.google.common.base.Preconditions; -import com.google.common.base.Splitter; -import com.google.common.base.Strings; -import com.google.common.collect.Iterators; -import com.google.common.net.InetAddresses; -import com.google.common.primitives.UnsignedBytes; +import java.math.BigInteger; import java.net.Inet4Address; import java.net.InetAddress; import java.net.UnknownHostException; +import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IetfInetUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; 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 com.google.common.base.Preconditions; +import com.google.common.base.Splitter; +import com.google.common.base.Strings; +import com.google.common.collect.Iterators; +import com.google.common.net.InetAddresses; +import com.google.common.primitives.UnsignedBytes; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DottedQuad; /** * Created by Martin Bobak <mbobak@cisco.com> on 5.3.2015. * v6 routines added by Anton Ivanov on 14.6.2015 + * Arbitrary masks by sai.marapareddy@gmail.com */ public final class IpConversionUtil { + private static final Logger LOG = LoggerFactory.getLogger(IpConversionUtil.class); public static final String PREFIX_SEPARATOR = "/"; public static final Splitter PREFIX_SPLITTER = Splitter.on('/'); private static final int INADDR4SZ = 4; private static final int INADDR6SZ = 16; private static final int INT16SZ = 2; + private static final int IPV4_ADDRESS_LENGTH = 32; + private static final int IPV6_ADDRESS_LENGTH = 128; + private static final String DEFAULT_ARBITRARY_BIT_MASK = "255.255.255.255"; + + /* + * Prefix bytearray lookup table. We concatenate the prefixes + * to a single byte array and perform offset lookups to ensure + * the table is contiguous and save some space. + */ + private static final byte[] PREFIX_BYTEARRAYS; + static { + final byte[] a = new byte[(INADDR6SZ * Byte.SIZE + 1) * INADDR6SZ]; + + int offset = 0; + for (int p = 0; p <= INADDR6SZ * Byte.SIZE; ++p) { + int prefix = p; + for (int i = 0; i < INADDR6SZ; ++i) { + a[offset++] = (byte) nextNibble(prefix); + prefix -= Byte.SIZE; + } + } + + PREFIX_BYTEARRAYS = a; + } private IpConversionUtil() { throw new UnsupportedOperationException("This class should not be instantiated."); @@ -48,7 +79,7 @@ public final class IpConversionUtil { public static Iterator splitToParts(final Ipv4Address ipv4Address) { /* Invalid (Ab)use of ip address as prefix!!! */ - return Iterators.forArray(ipv4Address.getValue(), "32"); + return Iterators.forArray(ipv4Address.getValue(), String.valueOf(IPV4_ADDRESS_LENGTH)); } public static Iterator splitToParts(final Ipv6Prefix ipv6Prefix) { @@ -57,7 +88,7 @@ public final class IpConversionUtil { public static Iterator splitToParts(final Ipv6Address ipv6Address) { /* Invalid (Ab)use of ip address as prefix!!! */ - return Iterators.forArray(ipv6Address.getValue(), "128"); + return Iterators.forArray(ipv6Address.getValue(), String.valueOf(IPV6_ADDRESS_LENGTH)); } /* This forest of functions has a purpose: @@ -72,7 +103,7 @@ public final class IpConversionUtil { */ public static Ipv4Prefix createPrefix(final Ipv4Address ipv4Address){ - return new Ipv4Prefix(ipv4Address.getValue() + PREFIX_SEPARATOR + 32); + return IetfInetUtil.INSTANCE.ipv4PrefixFor(ipv4Address); } public static Ipv4Prefix createPrefix(final Ipv4Address ipv4Address, final String mask){ @@ -85,20 +116,30 @@ public final class IpConversionUtil { if (null != mask && !mask.isEmpty()) { return new Ipv4Prefix(ipv4Address.getValue() + PREFIX_SEPARATOR + mask); } else { - return new Ipv4Prefix(ipv4Address.getValue() + PREFIX_SEPARATOR + "32"); + return new Ipv4Prefix(ipv4Address.getValue() + PREFIX_SEPARATOR + IPV4_ADDRESS_LENGTH); } } public static Ipv4Prefix createPrefix(final Ipv4Address ipv4Address, final int intmask){ - return createPrefix(ipv4Address, String.valueOf(intmask)); + return IetfInetUtil.INSTANCE.ipv4PrefixFor(ipv4Address, intmask); } public static Ipv4Prefix createPrefix(final Ipv4Address ipv4Address, final byte [] bytemask){ - return createPrefix(ipv4Address, String.valueOf(countBits(bytemask))); + return IetfInetUtil.INSTANCE.ipv4PrefixFor(ipv4Address, countBits(bytemask)); + } + + public static DottedQuad createArbitraryBitMask(final byte [] bytemask) { + DottedQuad dottedQuad = new DottedQuad(DEFAULT_ARBITRARY_BIT_MASK); + try { + dottedQuad = new DottedQuad(InetAddress.getByAddress(bytemask).getHostAddress()); + } catch (UnknownHostException e) { + LOG.error("Failed to create the dottedQuad notation for the given mask ", e); + } + return dottedQuad; } public static Ipv6Prefix createPrefix(final Ipv6Address ipv6Address){ - return new Ipv6Prefix(ipv6Address.getValue() + PREFIX_SEPARATOR + 128); + return IetfInetUtil.INSTANCE.ipv6PrefixFor(ipv6Address); } public static Ipv6Prefix createPrefix(final Ipv6Address ipv6Address, final String mask){ @@ -109,48 +150,30 @@ public final class IpConversionUtil { * Note - there is no canonical form check here!!! */ if (Strings.isNullOrEmpty(mask)) { - return new Ipv6Prefix(ipv6Address.getValue() + PREFIX_SEPARATOR + "128"); + return new Ipv6Prefix(ipv6Address.getValue() + PREFIX_SEPARATOR + String.valueOf(IPV6_ADDRESS_LENGTH)); } else { return new Ipv6Prefix(ipv6Address.getValue() + PREFIX_SEPARATOR + mask); } } public static Ipv6Prefix createPrefix(final Ipv6Address ipv6Address, final int intmask){ - return createPrefix(ipv6Address, String.valueOf(intmask)); + return IetfInetUtil.INSTANCE.ipv6PrefixFor(ipv6Address, intmask); } public static Ipv6Prefix createPrefix(final Ipv6Address ipv6Address, final byte [] bytemask){ - /* - * Ipv4Address has already validated the address part of the prefix, - * It is mandated to comply to the same regexp as the address - * There is absolutely no point rerunning additional checks vs this - * Note - there is no canonical form check here!!! - */ - return createPrefix(ipv6Address, String.valueOf(countBits(bytemask))); + return IetfInetUtil.INSTANCE.ipv6PrefixFor(ipv6Address, countBits(bytemask)); } public static Integer extractPrefix(final Ipv4Prefix ipv4Prefix) { - Iterator addressParts = splitToParts(ipv4Prefix); - addressParts.next(); - Integer retval = null; - if (addressParts.hasNext()) { - retval = Integer.parseInt(addressParts.next()); - } - return retval; + return IetfInetUtil.INSTANCE.splitIpv4Prefix(ipv4Prefix).getValue(); } public static Integer extractPrefix(final Ipv6Prefix ipv6Prefix) { - Iterator addressParts = splitToParts(ipv6Prefix); - addressParts.next(); - Integer retval = null; - if (addressParts.hasNext()) { - retval = Integer.parseInt(addressParts.next()); - } - return retval; + return IetfInetUtil.INSTANCE.splitIpv6Prefix(ipv6Prefix).getValue(); } public static Integer extractPrefix(final Ipv4Address ipv4Prefix) { - return 32; + return IPV4_ADDRESS_LENGTH; } public static Integer extractPrefix(final Ipv6Address ipv6Prefix) { @@ -500,8 +523,9 @@ public final class IpConversionUtil { /** * Print a v6 prefix in byte array + 1 notation - * * @param _binary_form - prefix, in byte [] form, last byte is netmask + * @return string of v6 prefix + * @throws UnknownHostException unknown host exception */ public static String byteArrayV6PrefixToString(final byte [] _binary_form) throws UnknownHostException { /* NO DIY!!! - InetAddresses will actually print correct canonical @@ -523,44 +547,45 @@ public final class IpConversionUtil { return sb.toString(); } + private static int ipv6PrefixByteArrayOffset(final int mask) { + if (mask < 0) { + return 0; + } - /** + final int ret = mask * INADDR6SZ; + if (ret < PREFIX_BYTEARRAYS.length) { + return ret; + } else { + return PREFIX_BYTEARRAYS.length - INADDR6SZ; + } + } + + /** * Canonicalize a v6 prefix while in binary form * - * @param _prefix - prefix, in byte [] form + * @param prefix - prefix, in byte [] form * @param mask - mask - number of bits */ - public static void canonicalizeIpv6Prefix(final byte [] _prefix, int mask) { + public static void canonicalizeIpv6Prefix(final byte [] prefix, final int mask) { + final int offset = ipv6PrefixByteArrayOffset(mask); - for (int i=0; i < INADDR6SZ; i++) { - _prefix[i] = (byte) (_prefix[i] & nextNibble(mask)); - mask = mask - 8; + for (int i = 0; i < INADDR6SZ; i++) { + prefix[i] &= PREFIX_BYTEARRAYS[offset + i]; } } - public static byte[] convertIpv6PrefixToByteArray(int prefix) { - byte[] mask = new byte[16]; - for (int count = 0; count < 16; count++) { - mask[count] = (byte) nextNibble(prefix); - prefix = prefix - 8; - } - return mask; + public static byte[] convertIpv6PrefixToByteArray(final int prefix) { + final int offset = ipv6PrefixByteArrayOffset(prefix); + + return Arrays.copyOfRange(PREFIX_BYTEARRAYS, offset, offset + INADDR6SZ); } public static Ipv6Address extractIpv6Address(final Ipv6Prefix ipv6Prefix) { - Iterator addressParts = PREFIX_SPLITTER.split(ipv6Prefix.getValue()).iterator(); - return new Ipv6Address(addressParts.next()); + return IetfInetUtil.INSTANCE.ipv6AddressFrom(ipv6Prefix); } public static Integer extractIpv6Prefix(final Ipv6Prefix ipv6Prefix) { - Iterator addressParts = PREFIX_SPLITTER.split(ipv6Prefix.getValue()).iterator(); - addressParts.next(); - - Integer prefix = null; - if (addressParts.hasNext()) { - prefix = Integer.parseInt(addressParts.next()); - } - return prefix; + return IetfInetUtil.INSTANCE.splitIpv6Prefix(ipv6Prefix).getValue(); } public static int countBits(final byte[] mask) { @@ -570,4 +595,55 @@ public final class IpConversionUtil { } return netmask; } + + public static final byte[] convertArbitraryMaskToByteArray(DottedQuad mask) { + String maskValue; + if (mask != null && mask.getValue() != null){ + maskValue = mask.getValue(); + } + else { + maskValue = DEFAULT_ARBITRARY_BIT_MASK; + } + InetAddress maskInIpFormat = null; + try { + maskInIpFormat = InetAddress.getByName(maskValue); + } catch (UnknownHostException e) { + LOG.error ("Failed to resolve the ip address of the mask",e); + } + byte[] bytes = maskInIpFormat.getAddress(); + return bytes; + } + + public static boolean isArbitraryBitMask(byte[] byteMask) { + if (byteMask == null) { + return false; + } + else { + ArrayList integerMaskArrayList = new ArrayList(); + String maskInBits; + // converting byte array to bits + maskInBits = new BigInteger(1, byteMask).toString(2); + ArrayList stringMaskArrayList = new ArrayList(Arrays.asList(maskInBits.split("(?!^)"))); + for(String string:stringMaskArrayList){ + integerMaskArrayList.add(Integer.parseInt(string)); + } + return checkArbitraryBitMask(integerMaskArrayList); + } + } + + private static boolean checkArbitraryBitMask(ArrayList arrayList) { + // checks 0*1* case - Leading zeros in arrayList are truncated + if(arrayList.size()>0 && arrayList.size()<32) { + return true; + } + //checks 1*0*1 case + else { + for(int i=0; i