From: Michal Rehak Date: Wed, 11 Dec 2013 15:19:08 +0000 (+0100) Subject: added length check for mask X-Git-Tag: jenkins-openflowjava-bulk-release-prepare-only-1~29 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=885ec87fa6b1ae4d851fe3a212a3044535dbd730;p=openflowjava.git added length check for mask minor refactor Change-Id: I894e517a211affe3498721d72ace60cc7bf49ff1 Signed-off-by: Michal Rehak --- diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/ByteBufUtils.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/ByteBufUtils.java index a1dced8f..06af9d4f 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/ByteBufUtils.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/ByteBufUtils.java @@ -166,7 +166,7 @@ public abstract class ByteBufUtils { public static String bytesToHexString(byte[] array) { StringBuffer sb = new StringBuffer(); for (int i = 0; i < array.length; i++) { - short b = array[i]; + byte b = array[i]; sb.append(String.format("%02x ", b)); } return sb.toString(); diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchSerializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchSerializer.java index 5ba7a187..74ace299 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchSerializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchSerializer.java @@ -171,11 +171,11 @@ public class MatchSerializer { Class field = entry.getOxmMatchField(); if (field.isAssignableFrom(InPort.class)) { fieldValue = 0; - writeOxmFieldAndLength(out, fieldValue, EncodeConstants.SIZE_OF_INT_IN_BYTES); + writeOxmFieldAndLength(out, fieldValue, false, EncodeConstants.SIZE_OF_INT_IN_BYTES); out.writeInt(entry.getAugmentation(PortNumberMatchEntry.class).getPortNumber().getValue().intValue()); } else if (field.isAssignableFrom(InPhyPort.class)) { fieldValue = 1; - writeOxmFieldAndLength(out, fieldValue, EncodeConstants.SIZE_OF_INT_IN_BYTES); + writeOxmFieldAndLength(out, fieldValue, false, EncodeConstants.SIZE_OF_INT_IN_BYTES); out.writeInt(entry.getAugmentation(PortNumberMatchEntry.class).getPortNumber().getValue().intValue()); } else if (field.isAssignableFrom(Metadata.class)) { fieldValue = 2; @@ -188,43 +188,36 @@ public class MatchSerializer { writeMacAddressRelatedEntry(entry, out, fieldValue); } else if (field.isAssignableFrom(EthType.class)) { fieldValue = 5; - writeOxmFieldAndLength(out, fieldValue, EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + writeOxmFieldAndLength(out, fieldValue, false, EncodeConstants.SIZE_OF_SHORT_IN_BYTES); out.writeShort(entry.getAugmentation(EthTypeMatchEntry.class).getEthType().getValue().shortValue()); } else if (field.isAssignableFrom(VlanVid.class)) { fieldValue = 6; - fieldValue = fieldValue << 1; VlanVidMatchEntry vlanVid = entry.getAugmentation(VlanVidMatchEntry.class); int vlanVidValue = vlanVid.getVlanVid(); if (vlanVid.isCfiBit()) { short cfi = 1 << 12; // 13-th bit vlanVidValue = vlanVidValue | cfi; } - if (entry.isHasMask()) { - fieldValue = fieldValue | 1; - out.writeByte(fieldValue); - byte[] mask = entry.getAugmentation(MaskMatchEntry.class).getMask(); - out.writeByte(EncodeConstants.SIZE_OF_SHORT_IN_BYTES + mask.length); - out.writeShort(vlanVidValue); - out.writeBytes(mask); - } else { - writeOxmFieldAndLength(out, fieldValue, EncodeConstants.SIZE_OF_SHORT_IN_BYTES); - out.writeShort(vlanVidValue); - } + + writeOxmFieldAndLength(out, fieldValue, entry.isHasMask(), + EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + out.writeShort(vlanVidValue); + writeMask(entry, out, EncodeConstants.SIZE_OF_SHORT_IN_BYTES); } else if (field.isAssignableFrom(VlanPcp.class)) { fieldValue = 7; - writeOxmFieldAndLength(out, fieldValue, EncodeConstants.SIZE_OF_BYTE_IN_BYTES); + writeOxmFieldAndLength(out, fieldValue, false, EncodeConstants.SIZE_OF_BYTE_IN_BYTES); out.writeByte(entry.getAugmentation(VlanPcpMatchEntry.class).getVlanPcp().byteValue()); } else if (field.isAssignableFrom(IpDscp.class)) { fieldValue = 8; - writeOxmFieldAndLength(out, fieldValue, EncodeConstants.SIZE_OF_BYTE_IN_BYTES); + writeOxmFieldAndLength(out, fieldValue, false, EncodeConstants.SIZE_OF_BYTE_IN_BYTES); out.writeByte(entry.getAugmentation(DscpMatchEntry.class).getDscp().getValue()); } else if (field.isAssignableFrom(IpEcn.class)) { fieldValue = 9; - writeOxmFieldAndLength(out, fieldValue, EncodeConstants.SIZE_OF_BYTE_IN_BYTES); + writeOxmFieldAndLength(out, fieldValue, false, EncodeConstants.SIZE_OF_BYTE_IN_BYTES); out.writeByte(entry.getAugmentation(EcnMatchEntry.class).getEcn()); } else if (field.isAssignableFrom(IpProto.class)) { fieldValue = 10; - writeOxmFieldAndLength(out, fieldValue, EncodeConstants.SIZE_OF_BYTE_IN_BYTES); + writeOxmFieldAndLength(out, fieldValue, false, EncodeConstants.SIZE_OF_BYTE_IN_BYTES); out.writeByte(entry.getAugmentation(ProtocolNumberMatchEntry.class).getProtocolNumber()); } else if (field.isAssignableFrom(Ipv4Src.class)) { fieldValue = 11; @@ -234,39 +227,39 @@ public class MatchSerializer { writeIpv4AddressRelatedEntry(entry, out, fieldValue); } else if (field.isAssignableFrom(TcpSrc.class)) { fieldValue = 13; - writeOxmFieldAndLength(out, fieldValue, EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + writeOxmFieldAndLength(out, fieldValue, false, EncodeConstants.SIZE_OF_SHORT_IN_BYTES); out.writeShort(entry.getAugmentation(PortMatchEntry.class).getPort().getValue().intValue()); } else if (field.isAssignableFrom(TcpDst.class)) { fieldValue = 14; - writeOxmFieldAndLength(out, fieldValue, EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + writeOxmFieldAndLength(out, fieldValue, false, EncodeConstants.SIZE_OF_SHORT_IN_BYTES); out.writeShort(entry.getAugmentation(PortMatchEntry.class).getPort().getValue().intValue()); } else if (field.isAssignableFrom(UdpSrc.class)) { fieldValue = 15; - writeOxmFieldAndLength(out, fieldValue, EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + writeOxmFieldAndLength(out, fieldValue, false, EncodeConstants.SIZE_OF_SHORT_IN_BYTES); out.writeShort(entry.getAugmentation(PortMatchEntry.class).getPort().getValue().intValue()); } else if (field.isAssignableFrom(UdpDst.class)) { fieldValue = 16; - writeOxmFieldAndLength(out, fieldValue, EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + writeOxmFieldAndLength(out, fieldValue, false, EncodeConstants.SIZE_OF_SHORT_IN_BYTES); out.writeShort(entry.getAugmentation(PortMatchEntry.class).getPort().getValue().intValue()); } else if (field.isAssignableFrom(SctpSrc.class)) { fieldValue = 17; - writeOxmFieldAndLength(out, fieldValue, EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + writeOxmFieldAndLength(out, fieldValue, false, EncodeConstants.SIZE_OF_SHORT_IN_BYTES); out.writeShort(entry.getAugmentation(PortMatchEntry.class).getPort().getValue().intValue()); } else if (field.isAssignableFrom(SctpDst.class)) { fieldValue = 18; - writeOxmFieldAndLength(out, fieldValue, EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + writeOxmFieldAndLength(out, fieldValue, false, EncodeConstants.SIZE_OF_SHORT_IN_BYTES); out.writeShort(entry.getAugmentation(PortMatchEntry.class).getPort().getValue().intValue()); } else if (field.isAssignableFrom(Icmpv4Type.class)) { fieldValue = 19; - writeOxmFieldAndLength(out, fieldValue, EncodeConstants.SIZE_OF_BYTE_IN_BYTES); + writeOxmFieldAndLength(out, fieldValue, false, EncodeConstants.SIZE_OF_BYTE_IN_BYTES); out.writeByte(entry.getAugmentation(Icmpv4TypeMatchEntry.class).getIcmpv4Type()); } else if (field.isAssignableFrom(Icmpv4Code.class)) { fieldValue = 20; - writeOxmFieldAndLength(out, fieldValue, EncodeConstants.SIZE_OF_BYTE_IN_BYTES); + writeOxmFieldAndLength(out, fieldValue, false, EncodeConstants.SIZE_OF_BYTE_IN_BYTES); out.writeByte(entry.getAugmentation(Icmpv4CodeMatchEntry.class).getIcmpv4Code()); } else if (field.isAssignableFrom(ArpOp.class)) { fieldValue = 21; - writeOxmFieldAndLength(out, fieldValue, EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + writeOxmFieldAndLength(out, fieldValue, false, EncodeConstants.SIZE_OF_SHORT_IN_BYTES); out.writeShort(entry.getAugmentation(OpCodeMatchEntry.class).getOpCode()); } else if (field.isAssignableFrom(ArpSpa.class)) { fieldValue = 22; @@ -288,28 +281,17 @@ public class MatchSerializer { writeIpv6AddressRelatedEntry(entry, out, fieldValue); } else if (field.isAssignableFrom(Ipv6Flabel.class)) { fieldValue = 28; - fieldValue = fieldValue << 1; - if (entry.isHasMask()) { - fieldValue = fieldValue | 1; - out.writeByte(fieldValue); - byte[] mask = entry.getAugmentation(MaskMatchEntry.class).getMask(); - out.writeByte(EncodeConstants.SIZE_OF_INT_IN_BYTES + mask.length); // 20 b + mask [OF 1.3.2 spec] - LOGGER.warn("Ipv6Flabel match entry: possible wrong length written (wrote 4 - maybe must be 3)"); - out.writeInt(entry.getAugmentation(Ipv6FlabelMatchEntry.class).getIpv6Flabel().getValue().intValue()); - out.writeBytes(entry.getAugmentation(MaskMatchEntry.class).getMask()); - } else { - out.writeByte(fieldValue); - out.writeByte(EncodeConstants.SIZE_OF_INT_IN_BYTES); // 20 b [OF 1.3.2 spec] - LOGGER.warn("Ipv6Flabel match entry: possible wrong length written (wrote 4 - maybe must be 3)"); - out.writeInt(entry.getAugmentation(Ipv6FlabelMatchEntry.class).getIpv6Flabel().getValue().intValue()); - } + writeOxmFieldAndLength(out, fieldValue, entry.isHasMask(), + EncodeConstants.SIZE_OF_INT_IN_BYTES); + out.writeInt(entry.getAugmentation(Ipv6FlabelMatchEntry.class).getIpv6Flabel().getValue().intValue()); + writeMask(entry, out, EncodeConstants.SIZE_OF_INT_IN_BYTES); } else if (field.isAssignableFrom(Icmpv6Type.class)) { fieldValue = 29; - writeOxmFieldAndLength(out, fieldValue, EncodeConstants.SIZE_OF_BYTE_IN_BYTES); + writeOxmFieldAndLength(out, fieldValue, false, EncodeConstants.SIZE_OF_BYTE_IN_BYTES); out.writeByte(entry.getAugmentation(Icmpv6TypeMatchEntry.class).getIcmpv6Type()); } else if (field.isAssignableFrom(Icmpv6Code.class)) { fieldValue = 30; - writeOxmFieldAndLength(out, fieldValue, EncodeConstants.SIZE_OF_BYTE_IN_BYTES); + writeOxmFieldAndLength(out, fieldValue, false, EncodeConstants.SIZE_OF_BYTE_IN_BYTES); out.writeByte(entry.getAugmentation(Icmpv6CodeMatchEntry.class).getIcmpv6Code()); } else if (field.isAssignableFrom(Ipv6NdTarget.class)) { fieldValue = 31; @@ -322,34 +304,23 @@ public class MatchSerializer { writeMacAddressRelatedEntry(entry, out, fieldValue); } else if (field.isAssignableFrom(MplsLabel.class)) { fieldValue = 34; - writeOxmFieldAndLength(out, fieldValue, EncodeConstants.SIZE_OF_INT_IN_BYTES); + writeOxmFieldAndLength(out, fieldValue, false, EncodeConstants.SIZE_OF_INT_IN_BYTES); LOGGER.warn("MplsLabel match entry: possible wrong length written (wrote 4 - maybe must be 3)"); out.writeInt(entry.getAugmentation(MplsLabelMatchEntry.class).getMplsLabel().intValue()); } else if (field.isAssignableFrom(MplsTc.class)) { fieldValue = 35; - writeOxmFieldAndLength(out, fieldValue, EncodeConstants.SIZE_OF_BYTE_IN_BYTES); + writeOxmFieldAndLength(out, fieldValue, false, EncodeConstants.SIZE_OF_BYTE_IN_BYTES); out.writeByte(entry.getAugmentation(TcMatchEntry.class).getTc()); } else if (field.isAssignableFrom(MplsBos.class)) { fieldValue = 36; - writeOxmFieldAndLength(out, fieldValue, EncodeConstants.SIZE_OF_BYTE_IN_BYTES); + writeOxmFieldAndLength(out, fieldValue, false, EncodeConstants.SIZE_OF_BYTE_IN_BYTES); out.writeBoolean(entry.getAugmentation(BosMatchEntry.class).isBos().booleanValue()); } else if (field.isAssignableFrom(PbbIsid.class)) { fieldValue = 37; - fieldValue = fieldValue << 1; - if (entry.isHasMask()) { - fieldValue = fieldValue | 1; - out.writeByte(fieldValue); - byte[] mask = entry.getAugmentation(MaskMatchEntry.class).getMask(); - out.writeByte(EncodeConstants.SIZE_OF_LONG_IN_BYTES + mask.length); - LOGGER.warn("PbbIsid match entry: possible wrong length written (wrote 4 - maybe must be 3)"); - out.writeInt(entry.getAugmentation(IsidMatchEntry.class).getIsid().intValue()); - out.writeBytes(mask); - } else { - out.writeByte(fieldValue); - out.writeByte(EncodeConstants.SIZE_OF_LONG_IN_BYTES); - LOGGER.warn("PbbIsid match entry: possible wrong length written (wrote 4 - maybe must be 3)"); - out.writeInt(entry.getAugmentation(IsidMatchEntry.class).getIsid().intValue()); - } + writeOxmFieldAndLength(out, fieldValue, entry.isHasMask(), + EncodeConstants.SIZE_OF_LONG_IN_BYTES); + out.writeInt(entry.getAugmentation(IsidMatchEntry.class).getIsid().intValue()); + writeMask(entry, out, EncodeConstants.SIZE_OF_LONG_IN_BYTES); } else if (field.isAssignableFrom(TunnelId.class)) { fieldValue = 38; writeMetadataRelatedEntry(entry, out, fieldValue); @@ -368,75 +339,68 @@ public class MatchSerializer { map.put(7, pseudoField.isUnrep()); map.put(8, pseudoField.isUnseq()); int bitmap = ByteBufUtils.fillBitMaskFromMap(map); - if (entry.isHasMask()) { - fieldValue = fieldValue | 1; - out.writeByte(fieldValue); - byte[] mask = entry.getAugmentation(MaskMatchEntry.class).getMask(); - out.writeByte(EncodeConstants.SIZE_OF_SHORT_IN_BYTES + mask.length); - out.writeShort(bitmap); - out.writeBytes(mask); - } else { - out.writeByte(fieldValue); - out.writeByte(EncodeConstants.SIZE_OF_SHORT_IN_BYTES); - out.writeShort(bitmap); + + writeOxmFieldAndLength(out, fieldValue, entry.isHasMask(), + EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + out.writeShort(bitmap); + writeMask(entry, out, EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + } + } + + /** + * @param entry + * @param out + * @param length TODO + */ + private static void writeMask(MatchEntries entry, ByteBuf out, int length) { + if (entry.isHasMask()) { + byte[] mask = entry.getAugmentation(MaskMatchEntry.class).getMask(); + if (mask != null && mask.length != length) { + throw new IllegalArgumentException("incorrect length of mask: "+ + mask.length + ", expected: " + length); } + out.writeBytes(mask); } } - private static void writeOxmFieldAndLength(ByteBuf out, int fieldValue, int length) { + private static void writeOxmFieldAndLength(ByteBuf out, int fieldValue, boolean hasMask, int lengthArg) { int fieldAndMask = fieldValue << 1; + int length = lengthArg; + if (hasMask) { + fieldAndMask |= 1; + length *= 2; + } + out.writeByte(fieldAndMask); out.writeByte(length); + } private static void writeMetadataRelatedEntry(MatchEntries entry, ByteBuf out, int value) { - int fieldValue = value << 1; - if (entry.isHasMask()) { - fieldValue = fieldValue | 1; - out.writeByte(fieldValue); - byte[] mask = entry.getAugmentation(MaskMatchEntry.class).getMask(); - out.writeByte(EncodeConstants.SIZE_OF_LONG_IN_BYTES + mask.length); - out.writeBytes(entry.getAugmentation(MetadataMatchEntry.class).getMetadata()); - out.writeBytes(mask); - } else { - out.writeByte(fieldValue); - out.writeByte(EncodeConstants.SIZE_OF_LONG_IN_BYTES); - out.writeBytes(entry.getAugmentation(MetadataMatchEntry.class).getMetadata()); - } + int fieldValue = value; + writeOxmFieldAndLength(out, fieldValue, entry.isHasMask(), + EncodeConstants.SIZE_OF_LONG_IN_BYTES); + out.writeBytes(entry.getAugmentation(MetadataMatchEntry.class).getMetadata()); + writeMask(entry, out, EncodeConstants.SIZE_OF_LONG_IN_BYTES); } private static void writeMacAddressRelatedEntry(MatchEntries entry, ByteBuf out, int value) { - int fieldValue = value << 1; - if (entry.isHasMask()) { - fieldValue = fieldValue | 1; - out.writeByte(fieldValue); - byte[] mask = entry.getAugmentation(MaskMatchEntry.class).getMask(); - out.writeByte(EncodeConstants.MAC_ADDRESS_LENGTH + mask.length); // 48 b + mask [OF 1.3.2 spec] - String macAddress = entry.getAugmentation(MacAddressMatchEntry.class).getMacAddress().getValue(); - out.writeBytes(ByteBufUtils.macAddressToBytes(macAddress)); - out.writeBytes(mask); - } else { - out.writeByte(fieldValue); - out.writeByte(EncodeConstants.MAC_ADDRESS_LENGTH); // 48 b [OF 1.3.2 spec] - String macAddress = entry.getAugmentation(MacAddressMatchEntry.class).getMacAddress().getValue(); - out.writeBytes(ByteBufUtils.macAddressToBytes(macAddress)); - } + int fieldValue = value; + + writeOxmFieldAndLength(out, fieldValue, entry.isHasMask(), + EncodeConstants.MAC_ADDRESS_LENGTH); + String macAddress = entry.getAugmentation(MacAddressMatchEntry.class).getMacAddress().getValue(); + out.writeBytes(ByteBufUtils.macAddressToBytes(macAddress)); // 48 b + mask [OF 1.3.2 spec] + writeMask(entry, out, EncodeConstants.MAC_ADDRESS_LENGTH); } private static void writeIpv4AddressRelatedEntry(MatchEntries entry, ByteBuf out, int value) { - int fieldValue = value << 1; - if (entry.isHasMask()) { - fieldValue = fieldValue | 1; - out.writeByte(fieldValue); - byte[] mask = entry.getAugmentation(MaskMatchEntry.class).getMask(); - out.writeByte(EncodeConstants.SIZE_OF_INT_IN_BYTES + mask.length); - writeIpv4Address(entry, out); - out.writeBytes(mask); - } else { - out.writeByte(fieldValue); - out.writeByte(EncodeConstants.SIZE_OF_INT_IN_BYTES); - writeIpv4Address(entry, out); - } + int fieldValue = value; + + writeOxmFieldAndLength(out, fieldValue, entry.isHasMask(), + EncodeConstants.SIZE_OF_INT_IN_BYTES); + writeIpv4Address(entry, out); + writeMask(entry, out, EncodeConstants.SIZE_OF_INT_IN_BYTES); } private static void writeIpv4Address(MatchEntries entry, ByteBuf out) { @@ -447,7 +411,7 @@ public class MatchSerializer { } private static void writeIpv6AddressRelatedEntry(MatchEntries entry, ByteBuf out, int value) { - int fieldValue = value << 1; + int fieldValue = value; String textAddress = entry.getAugmentation(Ipv6AddressMatchEntry.class).getIpv6Address().getValue(); String[] address; if (textAddress.equals("::")) { @@ -456,22 +420,13 @@ public class MatchSerializer { } else { address = parseIpv6Address(textAddress.split(":")); } - if (entry.isHasMask()) { - fieldValue = fieldValue | 1; - out.writeByte(fieldValue); - byte[] mask = entry.getAugmentation(MaskMatchEntry.class).getMask(); - out.writeByte(EncodeConstants.SIZE_OF_IPV6_ADDRESS_IN_BYTES + mask.length); - for (int i = 0; i < address.length; i++) { - out.writeShort(Integer.parseInt(address[i], 16)); - } - out.writeBytes(mask); - } else { - out.writeByte(fieldValue); - out.writeByte(EncodeConstants.SIZE_OF_IPV6_ADDRESS_IN_BYTES); - for (int i = 0; i < address.length; i++) { - out.writeShort(Integer.parseInt(address[i], 16)); - } + + writeOxmFieldAndLength(out, fieldValue, entry.isHasMask(), + EncodeConstants.SIZE_OF_IPV6_ADDRESS_IN_BYTES); + for (int i = 0; i < address.length; i++) { + out.writeShort(Integer.parseInt(address[i], 16)); } + writeMask(entry, out, EncodeConstants.SIZE_OF_IPV6_ADDRESS_IN_BYTES); } private static String[] parseIpv6Address(String[] addressGroups) { diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/MatchSerializerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/MatchSerializerTest.java index 220e7bce..b605f942 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/MatchSerializerTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/MatchSerializerTest.java @@ -18,12 +18,18 @@ import org.junit.Assert; import org.junit.Test; 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.Ipv6Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6FlowLabel; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Ipv4AddressMatchEntry; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Ipv4AddressMatchEntryBuilder; 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.Ipv6FlabelMatchEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Ipv6FlabelMatchEntryBuilder; +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.Ipv4Src; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv6Dst; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv6Flabel; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv6NdTarget; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv6Src; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Nxm0Class; @@ -34,18 +40,23 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm. import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.MatchEntriesBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.match.grouping.Match; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.match.grouping.MatchBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * @author michal.polkorab * */ public class MatchSerializerTest { + + private static final Logger LOG = LoggerFactory + .getLogger(MatchSerializerTest.class); /** * Test for correct serialization of Ipv4Address match entry */ @Test - public void test() { + public void testIpv4Src() { MatchBuilder builder = new MatchBuilder(); builder.setType(OxmMatchType.class); List entries = new ArrayList<>(); @@ -78,7 +89,7 @@ public class MatchSerializerTest { * Test for correct serialization of Ipv6Address match entry */ @Test - public void test2() { + public void testIpv6Various() { MatchBuilder builder = new MatchBuilder(); builder.setType(OxmMatchType.class); List entries = new ArrayList<>(); @@ -210,5 +221,94 @@ public class MatchSerializerTest { Assert.assertEquals("Wrong ipv6 address", 7, out.readUnsignedShort()); Assert.assertEquals("Wrong ipv6 address", 8, out.readUnsignedShort()); } + + /** + * Test for correct serialization of Ipv4Address match entry + */ + @Test + public void testIpv6Flabel() { + Match match = buildIpv6FLabelMatch(0x0f9e8dL, false, null); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + MatchSerializer.encodeMatch(match, out); + + Assert.assertEquals("Wrong type", 1, out.readUnsignedShort()); + out.skipBytes(EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + Assert.assertEquals("Wrong class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong field and mask", 28<<1, out.readUnsignedByte()); + out.skipBytes(EncodeConstants.SIZE_OF_BYTE_IN_BYTES); + byte[] label = new byte[4]; + out.readBytes(label); + + LOG.debug("label: "+ByteBufUtils.bytesToHexString(label)); + Assert.assertArrayEquals("Wrong ipv6FLabel", new byte[]{0, 0x0f, (byte) 0x9e, (byte) 0x8d}, label); + } + + /** + * Test for correct serialization of Ipv4Address match entry with mask + */ + @Test + public void testIpv6FlabelWithMask() { + Match match = buildIpv6FLabelMatch(0x0f9e8dL, true, new byte[]{0, 0x0c, 0x7b, 0x6a}); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + MatchSerializer.encodeMatch(match, out); + + Assert.assertEquals("Wrong type", 1, out.readUnsignedShort()); + out.skipBytes(EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + Assert.assertEquals("Wrong class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong field and mask", 28<<1 | 1, out.readUnsignedByte()); + out.skipBytes(EncodeConstants.SIZE_OF_BYTE_IN_BYTES); + byte[] labelAndMask = new byte[8]; + out.readBytes(labelAndMask); + + LOG.debug("label: "+ByteBufUtils.bytesToHexString(labelAndMask)); + Assert.assertArrayEquals("Wrong ipv6FLabel", new byte[]{0, 0x0f, (byte) 0x9e, (byte) 0x8d, 0, 0x0c, 0x7b, 0x6a}, labelAndMask); + } + + /** + * Test for correct serialization of Ipv4Address match entry with wrong mask + */ + @Test + public void testIpv6FlabelWithMaskBad() { + Match match = buildIpv6FLabelMatch(0x0f9e8dL, true, new byte[]{0x0c, 0x7b, 0x6a}); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + + try { + MatchSerializer.encodeMatch(match, out); + Assert.fail("incorrect length of mask ignored"); + } catch (IllegalArgumentException e) { + //expected + } + } + + /** + * @param labelValue ipv6 flow label + * @param hasMask + * @param mask ipv6 flow label mask + * @return + */ + private static Match buildIpv6FLabelMatch(long labelValue, boolean hasMask, byte[] mask) { + MatchBuilder builder = new MatchBuilder(); + builder.setType(OxmMatchType.class); + List entries = new ArrayList<>(); + MatchEntriesBuilder entriesBuilder = new MatchEntriesBuilder(); + entriesBuilder.setOxmClass(OpenflowBasicClass.class); + entriesBuilder.setOxmMatchField(Ipv6Flabel.class); + entriesBuilder.setHasMask(hasMask); + Ipv6FlabelMatchEntryBuilder ip6FLabelBuilder = new Ipv6FlabelMatchEntryBuilder(); + ip6FLabelBuilder.setIpv6Flabel(new Ipv6FlowLabel(labelValue)); + entriesBuilder.addAugmentation(Ipv6FlabelMatchEntry.class, ip6FLabelBuilder.build()); + MaskMatchEntryBuilder maskBuilder = new MaskMatchEntryBuilder(); + maskBuilder.setMask(mask); + entriesBuilder.addAugmentation(MaskMatchEntry.class, maskBuilder.build()); + entries.add(entriesBuilder.build()); + builder.setMatchEntries(entries); + Match match = builder.build(); + return match; + } + + }