HONEYCOMB-339: fix ip6 address string to byte conversion 99/4799/1
authorMarek Gradzki <[email protected]>
Thu, 19 Jan 2017 08:54:45 +0000 (09:54 +0100)
committerJan Srnicek <[email protected]>
Fri, 20 Jan 2017 06:52:02 +0000 (06:52 +0000)
Change-Id: I8c1d20b2be23bce27903b9d4149f59d3b83aacaa
Signed-off-by: Marek Gradzki <[email protected]>
routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/factory/MultipathHopRequestFactory.java
routing/routing-impl/src/main/java/io/fd/hc2vpp/routing/write/factory/SimpleHopRequestFactory.java
vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/Ipv6Translator.java
vpp-common/vpp-translate-utils/src/test/java/io/fd/hc2vpp/common/translate/util/Ipv6TranslatorTest.java

index 4497e81..6df95a0 100644 (file)
@@ -128,7 +128,7 @@ public class MultipathHopRequestFactory extends BasicHopRequestFactory implement
                                                  final int primaryVrf, final int secondaryVrf,
                                                  final int classifyTableIndex, final boolean classifyIndexSet) {
         return flaglessAddDelRouteRequest(booleanToByte(isAdd), nextHopInterfaceIndex,
-                ipv6AddressNoZoneToArray(nextHopAddress.getValue()), nextHopWeight, toByte(1),
+                ipv6AddressNoZoneToArray(nextHopAddress), nextHopWeight, toByte(1),
                 ipv6AddressPrefixToArray(destinationAddress), extractPrefix(destinationAddress.getValue()), toByte(1),
                 primaryVrf, secondaryVrf, classifyTableIndex,
                 booleanToByte(classifyIndexSet));
index 98c36e4..60be15d 100644 (file)
@@ -127,7 +127,7 @@ public class SimpleHopRequestFactory extends BasicHopRequestFactory implements R
                                               final int primaryVrf, final int secondaryVrf,
                                               final int classifyTableIndex, final boolean classifyIndexSet) {
         return flaglessAddDelRouteRequest(booleanToByte(isAdd), nextHopInterfaceIndex,
-                ipv6AddressNoZoneToArray(nextHopAddress.getValue()), DEFAULT_HOP_WEIGHT, BYTE_TRUE,
+                ipv6AddressNoZoneToArray(nextHopAddress), DEFAULT_HOP_WEIGHT, BYTE_TRUE,
                 ipv6AddressPrefixToArray(destinationAddress), extractPrefix(destinationAddress.getValue()), BYTE_FALSE,
                 primaryVrf, secondaryVrf, classifyTableIndex, booleanToByte(classifyIndexSet));
     }
index 396391d..c4a4ba3 100644 (file)
@@ -24,10 +24,7 @@ import com.google.common.net.InetAddresses;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.util.Arrays;
-import java.util.List;
-import java.util.stream.Collectors;
 import javax.annotation.Nonnull;
-import org.apache.commons.lang3.StringUtils;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
@@ -39,32 +36,14 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.
  */
 public interface Ipv6Translator extends ByteDataTranslator {
 
-    default byte[] ipv6AddressNoZoneToArray(@Nonnull final String address) {
-        byte[] retval = new byte[16];
-
-        //splits address and add ommited zeros for easier parsing
-        List<String> segments = Arrays.asList(address.split(":"))
-                .stream()
-                .map(segment -> StringUtils.repeat('0', 4 - segment.length()) + segment)
-                .collect(Collectors.toList());
-
-        byte index = 0;
-        for (String segment : segments) {
-
-            String firstPart = segment.substring(0, 2);
-            String secondPart = segment.substring(2);
-
-            //first part should be ommited
-            if ("00".equals(firstPart)) {
-                index++;
-            } else {
-                retval[index++] = ((byte) Short.parseShort(firstPart, 16));
-            }
-
-            retval[index++] = ((byte) Short.parseShort(secondPart, 16));
-        }
-
-        return retval;
+    /**
+     * Transform Ipv6 address to a byte array acceptable by VPP. VPP expects incoming byte array to be in the same order
+     * as the address.
+     *
+     * @return byte array with address bytes
+     */
+    default byte[] ipv6AddressNoZoneToArray(@Nonnull final Ipv6Address address) {
+        return Impl.ipv6AddressNoZoneToArray(address.getValue());
     }
 
     /**
@@ -74,7 +53,7 @@ public interface Ipv6Translator extends ByteDataTranslator {
      * @return byte array with address bytes
      */
     default byte[] ipv6AddressNoZoneToArray(@Nonnull final Ipv6AddressNoZone ipv6Addr) {
-        return ipv6AddressNoZoneToArray(ipv6Addr.getValue());
+        return Impl.ipv6AddressNoZoneToArray(ipv6Addr.getValue());
     }
 
     /**
@@ -163,4 +142,15 @@ public interface Ipv6Translator extends ByteDataTranslator {
                     "Cannot create prefix for address[" + Arrays.toString(address) + "],prefix[" + prefix + "]");
         }
     }
+
+    class Impl {
+        private static byte[] ipv6AddressNoZoneToArray(@Nonnull final String address){
+            try {
+                // No lookup performed for literal ipv6 addresses
+                return InetAddress.getByName(address).getAddress();
+            } catch (UnknownHostException e) {
+                throw new IllegalArgumentException("Invalid address supplied", e);
+            }
+        }
+    }
 }
index 1099f68..a620cbd 100644 (file)
@@ -28,7 +28,17 @@ public class Ipv6TranslatorTest implements Ipv6Translator {
     public void testIpv6NoZone() {
         final Ipv6AddressNoZone ipv6Addr = new Ipv6AddressNoZone("3ffe:1900:4545:3:200:f8ff:fe21:67cf");
         byte[] bytes = ipv6AddressNoZoneToArray(ipv6Addr);
-        assertEquals((byte) 63, bytes[0]);
+        assertEquals((byte) 0x3f, bytes[0]);
+        final Ipv6AddressNoZone ivp6AddressNoZone = arrayToIpv6AddressNoZone(bytes);
+        assertEquals(ipv6Addr, ivp6AddressNoZone);
+    }
+
+    @Test
+    public void testIpv6NoZoneEmptyGroup() {
+        final Ipv6AddressNoZone ipv6Addr = new Ipv6AddressNoZone("10::10");
+        byte[] bytes = ipv6AddressNoZoneToArray(ipv6Addr);
+        assertEquals((byte) 0, bytes[0]);
+        assertEquals((byte) 0x10, bytes[1]);
         final Ipv6AddressNoZone ivp6AddressNoZone = arrayToIpv6AddressNoZone(bytes);
         assertEquals(ipv6Addr, ivp6AddressNoZone);
     }