Bug 2866 - Fixed ipv6 address parsing 12/16812/4
authorMichal Polkorab <michal.polkorab@pantheon.sk>
Thu, 19 Mar 2015 10:02:06 +0000 (11:02 +0100)
committerMichal Polkorab <michal.polkorab@pantheon.sk>
Thu, 26 Mar 2015 09:00:15 +0000 (10:00 +0100)
 - also added uni test with missing case

Change-Id: I4b0e15f1a1896ed63bc47ce326afea40ff18cc07
Signed-off-by: Michal Polkorab <michal.polkorab@pantheon.sk>
openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/AbstractOxmIpv6AddressSerializer.java
openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6SrcSerializerTest.java [new file with mode: 0644]

index 63b6f42ed5148aac03cc7e95b088ee1948d2d5b6..8848eec26d8508939996f2a536d9f0f5243d69b3 100644 (file)
@@ -9,16 +9,10 @@ package org.opendaylight.openflowjava.protocol.impl.serialization.match;
 \r
 import io.netty.buffer.ByteBuf;\r
 \r
-import java.util.ArrayList;\r
-import java.util.Arrays;\r
-import java.util.List;\r
-\r
-import org.opendaylight.openflowjava.util.ByteBufUtils;\r
-import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Ipv6AddressMatchEntry;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.grouping.MatchEntries;\r
 \r
-import com.google.common.collect.Lists;\r
+import com.google.common.net.InetAddresses;\r
 \r
 /**\r
  * Parent for Ipv6 address based match entry serializers\r
@@ -30,54 +24,12 @@ public abstract class AbstractOxmIpv6AddressSerializer extends AbstractOxmMatchE
     public void serialize(final MatchEntries entry, final ByteBuf outBuffer) {\r
         super.serialize(entry, outBuffer);\r
         String textAddress = entry.getAugmentation(Ipv6AddressMatchEntry.class).getIpv6Address().getValue();\r
-        List<String> address;\r
-        if (textAddress.equals("::")) {\r
-            String[] tmp = new String[EncodeConstants.GROUPS_IN_IPV6_ADDRESS];\r
-            Arrays.fill(tmp, "0");\r
-            address = Arrays.asList(tmp);\r
+        if (InetAddresses.isInetAddress(textAddress)) {\r
+            byte[] binaryAddress = InetAddresses.forString(textAddress).getAddress();\r
+            outBuffer.writeBytes(binaryAddress);\r
         } else {\r
-            address = parseIpv6Address(Lists.newArrayList(ByteBufUtils.COLON_SPLITTER.split(textAddress)));\r
-        }\r
-        for (String group : address) {\r
-            outBuffer.writeShort(Integer.parseInt(group, 16));\r
+            throw new IllegalArgumentException("Invalid ipv6 address received: " + textAddress);\r
         }\r
         writeMask(entry, outBuffer, getValueLength());\r
     }\r
-\r
-    private static List<String> parseIpv6Address(final ArrayList<String> addressGroups) {\r
-        int countEmpty = 0;\r
-        for (String group : addressGroups) {\r
-            if (group.equals("")) {\r
-                countEmpty++;\r
-            }\r
-        }\r
-        List<String> ready = new ArrayList<>(EncodeConstants.GROUPS_IN_IPV6_ADDRESS);\r
-        switch (countEmpty) {\r
-        case 0:\r
-            ready = addressGroups;\r
-            break;\r
-        case 1:\r
-            int zerosToBePushed = EncodeConstants.GROUPS_IN_IPV6_ADDRESS - addressGroups.size() + 1;\r
-            for (String group : addressGroups) {\r
-                if (group.equals("")) {\r
-                    for (int j = 0; j < zerosToBePushed; j++) {\r
-                        ready.add("0");\r
-                    }\r
-                } else {\r
-                    ready.add(group);\r
-                }\r
-            }\r
-            break;\r
-        case 2:\r
-            String[] tmp = new String[EncodeConstants.GROUPS_IN_IPV6_ADDRESS];\r
-            Arrays.fill(tmp, "0");\r
-            tmp[EncodeConstants.GROUPS_IN_IPV6_ADDRESS - 1] =\r
-                    addressGroups.get(addressGroups.size() - 1);\r
-            ready = Arrays.asList(tmp);\r
-            break;\r
-        default:\r
-            throw new IllegalStateException("Incorrect ipv6 address");\r
-        }\r
-        return ready;\r
-    }\r
 }\r
diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6SrcSerializerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6SrcSerializerTest.java
new file mode 100644 (file)
index 0000000..66efb04
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2015 Pantheon Technologies s.r.o. 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,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowjava.protocol.impl.serialization.match;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.PooledByteBufAllocator;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
+import org.opendaylight.openflowjava.protocol.api.util.OxmMatchConstants;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Ipv6AddressMatchEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Ipv6AddressMatchEntryBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MaskMatchEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MaskMatchEntryBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv6Src;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.OpenflowBasicClass;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.grouping.MatchEntriesBuilder;
+
+/**
+ * @author michal.polkorab
+ *
+ */
+public class OxmIpv6SrcSerializerTest {
+
+    OxmIpv6SrcSerializer serializer = new OxmIpv6SrcSerializer();
+
+    /**
+     * Test correct serialization
+     */
+    @Test
+    public void testSerializeWithoutMask() {
+        MatchEntriesBuilder builder = prepareMatchEntry(false, "aaaa:bbbb:1111:2222::");
+
+        ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer();
+        serializer.serialize(builder.build(), buffer);
+
+        checkHeader(buffer, false);
+        Assert.assertEquals("Wrong ipv6 address", 43690, buffer.readUnsignedShort());
+        Assert.assertEquals("Wrong ipv6 address", 48059, buffer.readUnsignedShort());
+        Assert.assertEquals("Wrong ipv6 address", 4369, buffer.readUnsignedShort());
+        Assert.assertEquals("Wrong ipv6 address", 8738, buffer.readUnsignedShort());
+        Assert.assertEquals("Wrong ipv6 address", 0, buffer.readUnsignedShort());
+        Assert.assertEquals("Wrong ipv6 address", 0, buffer.readUnsignedShort());
+        Assert.assertEquals("Wrong ipv6 address", 0, buffer.readUnsignedShort());
+        Assert.assertEquals("Wrong ipv6 address", 0, buffer.readUnsignedShort());
+        assertTrue("Unexpected data", buffer.readableBytes() == 0);
+    }
+
+    /**
+     * Test correct serialization
+     */
+    @Test
+    public void testSerializeWithLeadingZeros() {
+        MatchEntriesBuilder builder = prepareMatchEntry(false, "::aaaa:bbbb:1111:2222");
+
+        ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer();
+        serializer.serialize(builder.build(), buffer);
+
+        checkHeader(buffer, false);
+        Assert.assertEquals("Wrong ipv6 address", 0, buffer.readUnsignedShort());
+        Assert.assertEquals("Wrong ipv6 address", 0, buffer.readUnsignedShort());
+        Assert.assertEquals("Wrong ipv6 address", 0, buffer.readUnsignedShort());
+        Assert.assertEquals("Wrong ipv6 address", 0, buffer.readUnsignedShort());
+        Assert.assertEquals("Wrong ipv6 address", 43690, buffer.readUnsignedShort());
+        Assert.assertEquals("Wrong ipv6 address", 48059, buffer.readUnsignedShort());
+        Assert.assertEquals("Wrong ipv6 address", 4369, buffer.readUnsignedShort());
+        Assert.assertEquals("Wrong ipv6 address", 8738, buffer.readUnsignedShort());
+        assertTrue("Unexpected data", buffer.readableBytes() == 0);
+    }
+
+    private static MatchEntriesBuilder prepareMatchEntry(boolean hasMask, String value) {
+        MatchEntriesBuilder builder = prepareHeader(hasMask);
+        if (hasMask) {
+            MaskMatchEntryBuilder maskBuilder = new MaskMatchEntryBuilder();
+            maskBuilder.setMask(new byte[]{15, 15, 0, 0});
+            builder.addAugmentation(MaskMatchEntry.class, maskBuilder.build());
+        }
+        Ipv6AddressMatchEntryBuilder addressBuilder = new Ipv6AddressMatchEntryBuilder();
+        addressBuilder.setIpv6Address(new Ipv6Address(value));
+        builder.addAugmentation(Ipv6AddressMatchEntry.class, addressBuilder.build());
+        return builder;
+    }
+
+    private static MatchEntriesBuilder prepareHeader(boolean hasMask) {
+        MatchEntriesBuilder builder = new MatchEntriesBuilder();
+        builder.setOxmClass(OpenflowBasicClass.class);
+        builder.setOxmMatchField(Ipv6Src.class);
+        builder.setHasMask(hasMask);
+        return builder;
+    }
+
+    private static void checkHeader(ByteBuf buffer, boolean hasMask) {
+        assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, buffer.readUnsignedShort());
+        short fieldAndMask = buffer.readUnsignedByte();
+        assertEquals("Wrong oxm-field", OxmMatchConstants.IPV6_SRC, fieldAndMask >>> 1);
+        assertEquals("Wrong hasMask", hasMask, (fieldAndMask & 1) != 0);
+        if (hasMask) {
+            assertEquals("Wrong length", 2 * EncodeConstants.SIZE_OF_IPV6_ADDRESS_IN_BYTES,
+                    buffer.readUnsignedByte());
+        } else {
+            assertEquals("Wrong length", EncodeConstants.SIZE_OF_IPV6_ADDRESS_IN_BYTES, buffer.readUnsignedByte());
+        }
+    }
+}