From cf7fac1140c3fe632e57e225dcdc8c8396b738e2 Mon Sep 17 00:00:00 2001 From: Michal Polkorab Date: Fri, 15 Nov 2013 13:48:37 +0100 Subject: [PATCH] Quickfix - fixed missing output ByteBuf in MatchSerializer Signed-off-by: Michal Polkorab --- .../protocol/impl/util/MatchDeserializer.java | 1 - .../protocol/impl/util/MatchSerializer.java | 2 +- .../FlowModInputMessageFactoryTest.java | 98 +++++++++++++++++-- .../PacketOutInputMessageFactoryTest.java | 44 ++++++++- 4 files changed, 130 insertions(+), 15 deletions(-) diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchDeserializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchDeserializer.java index d17f3a0a..b5e6b486 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchDeserializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchDeserializer.java @@ -501,7 +501,6 @@ public abstract class MatchDeserializer { } private static void addMaskAugmentation(MatchEntriesBuilder builder, ByteBuf in, int matchEntryLength) { -// TODO - check if matchEntryLength is in bytes MaskMatchEntryBuilder maskBuilder = new MaskMatchEntryBuilder(); byte[] mask = new byte[matchEntryLength]; in.readBytes(mask); 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 a6dabe1c..7af3e11c 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 @@ -139,7 +139,7 @@ public class MatchSerializer { } for (MatchEntries entry : matchEntries) { encodeClass(entry.getOxmClass(), out); - encodeRest(entry, null); + encodeRest(entry, out); } } diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowModInputMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowModInputMessageFactoryTest.java index 28376ed6..7fcd9b88 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowModInputMessageFactoryTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowModInputMessageFactoryTest.java @@ -5,17 +5,39 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.UnpooledByteBufAllocator; import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; import org.junit.Assert; import org.junit.Test; import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.HelloMessageFactoryTest; import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.EcnMatchEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.EcnMatchEntryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MetadataInstruction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MetadataInstructionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortNumberMatchEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortNumberMatchEntryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.TableIdInstruction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.TableIdInstructionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.GotoTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.WriteMetadata; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.Instructions; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.InstructionsBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModCommand; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModFlags; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.InPhyPort; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.IpEcn; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Nxm0Class; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.OpenflowBasicClass; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.OxmMatchType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.MatchEntries; +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.FlowModInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.match.grouping.MatchBuilder; /** * @author timotej.kubas @@ -31,9 +53,9 @@ public class FlowModInputMessageFactoryTest { public void testFlowModInputMessageFactory() throws Exception { FlowModInputBuilder builder = new FlowModInputBuilder(); BufferHelper.setupHeader(builder); - byte[] cookie = new byte[]{0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}; + byte[] cookie = new byte[]{0x00, 0x01, 0x04, 0x01, 0x06, 0x00, 0x07, 0x01}; builder.setCookie(new BigInteger(cookie)); - byte[] cookieMask = new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + byte[] cookieMask = new byte[]{0x01, 0x05, 0x00, 0x00, 0x09, 0x30, 0x00, 0x30}; builder.setCookieMask(new BigInteger(cookieMask)); builder.setTableId(new TableId(65L)); builder.setCommand(FlowModCommand.forValue(2)); @@ -44,6 +66,40 @@ public class FlowModInputMessageFactoryTest { builder.setOutPort(new PortNumber(4422L)); builder.setOutGroup(98L); builder.setFlags(new FlowModFlags(true, false, true, false, true)); + MatchBuilder matchBuilder = new MatchBuilder(); + matchBuilder.setType(OxmMatchType.class); + List entries = new ArrayList<>(); + MatchEntriesBuilder entriesBuilder = new MatchEntriesBuilder(); + entriesBuilder.setOxmClass(OpenflowBasicClass.class); + entriesBuilder.setOxmMatchField(InPhyPort.class); + entriesBuilder.setHasMask(false); + PortNumberMatchEntryBuilder portNumberBuilder = new PortNumberMatchEntryBuilder(); + portNumberBuilder.setPortNumber(new PortNumber(42L)); + entriesBuilder.addAugmentation(PortNumberMatchEntry.class, portNumberBuilder.build()); + entries.add(entriesBuilder.build()); + entriesBuilder.setOxmClass(Nxm0Class.class); + entriesBuilder.setOxmMatchField(IpEcn.class); + entriesBuilder.setHasMask(false); + EcnMatchEntryBuilder ecnBuilder = new EcnMatchEntryBuilder(); + ecnBuilder.setEcn((short) 4); + entriesBuilder.addAugmentation(EcnMatchEntry.class, ecnBuilder.build()); + entries.add(entriesBuilder.build()); + matchBuilder.setMatchEntries(entries); + builder.setMatch(matchBuilder.build()); + List instructions = new ArrayList<>(); + InstructionsBuilder insBuilder = new InstructionsBuilder(); + insBuilder.setType(GotoTable.class); + TableIdInstructionBuilder idBuilder = new TableIdInstructionBuilder(); + idBuilder.setTableId((short) 43); + insBuilder.addAugmentation(TableIdInstruction.class, idBuilder.build()); + instructions.add(insBuilder.build()); + insBuilder.setType(WriteMetadata.class); + MetadataInstructionBuilder metaBuilder = new MetadataInstructionBuilder(); + metaBuilder.setMetadata(cookie); + metaBuilder.setMetadataMask(cookieMask); + insBuilder.addAugmentation(MetadataInstruction.class, metaBuilder.build()); + instructions.add(insBuilder.build()); + builder.setInstructions(instructions); FlowModInput message = builder.build(); ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); @@ -53,21 +109,47 @@ public class FlowModInputMessageFactoryTest { BufferHelper.checkHeaderV13(out, factory.getMessageType(), factory.computeLength(message)); Assert.assertEquals("Wrong cookie", message.getCookie().longValue(), out.readLong()); Assert.assertEquals("Wrong cookieMask", message.getCookieMask().longValue(), out.readLong()); - Assert.assertEquals("Wrong tableId", message.getTableId().getValue().intValue(), out.readByte()); - Assert.assertEquals("Wrong command", message.getCommand().getIntValue(), out.readByte()); + Assert.assertEquals("Wrong tableId", message.getTableId().getValue().intValue(), out.readUnsignedByte()); + Assert.assertEquals("Wrong command", message.getCommand().getIntValue(), out.readUnsignedByte()); Assert.assertEquals("Wrong idleTimeOut", message.getIdleTimeout().intValue(), out.readShort()); Assert.assertEquals("Wrong hardTimeOut", message.getHardTimeout().intValue(), out.readShort()); Assert.assertEquals("Wrong priority", message.getPriority().intValue(), out.readUnsignedShort()); Assert.assertEquals("Wrong bufferId", message.getBufferId().intValue(), out.readUnsignedInt()); Assert.assertEquals("Wrong outPort", message.getOutPort().getValue().intValue(), out.readUnsignedInt()); Assert.assertEquals("Wrong outGroup", message.getOutGroup().intValue(), out.readUnsignedInt()); - Assert.assertEquals("Wrong flags", message.getFlags(), createFlowModFalgsFromBitmap(out.readShort())); + Assert.assertEquals("Wrong flags", message.getFlags(), createFlowModFlagsFromBitmap(out.readUnsignedShort())); out.skipBytes(PADDING_IN_FLOW_MOD_MESSAGE); - // TODO implementation of match structure - // TODO implementation of instructions + Assert.assertEquals("Wrong match type", 1, out.readUnsignedShort()); + out.skipBytes(Short.SIZE / Byte.SIZE); + Assert.assertEquals("Wrong oxm class", 0x8000, out.readUnsignedShort()); + short fieldAndMask = out.readUnsignedByte(); + Assert.assertEquals("Wrong oxm hasMask", 0, fieldAndMask & 1); + Assert.assertEquals("Wrong oxm field", 1, fieldAndMask >> 1); + out.skipBytes(Byte.SIZE / Byte.SIZE); + Assert.assertEquals("Wrong oxm value", 42, out.readUnsignedInt()); + Assert.assertEquals("Wrong oxm class", 0, out.readUnsignedShort()); + fieldAndMask = out.readUnsignedByte(); + Assert.assertEquals("Wrong oxm hasMask", 0, fieldAndMask & 1); + Assert.assertEquals("Wrong oxm field", 9, fieldAndMask >> 1); + out.skipBytes(Byte.SIZE / Byte.SIZE); + Assert.assertEquals("Wrong oxm value", 4, out.readUnsignedByte()); + out.skipBytes(7); + Assert.assertEquals("Wrong instruction type", 1, out.readUnsignedShort()); + out.skipBytes(Short.SIZE / Byte.SIZE); + Assert.assertEquals("Wrong instruction value", 43, out.readUnsignedByte()); + out.skipBytes(3); + Assert.assertEquals("Wrong instruction type", 2, out.readUnsignedShort()); + out.skipBytes(Short.SIZE / Byte.SIZE); + out.skipBytes(Integer.SIZE / Byte.SIZE); + byte[] cookieRead = new byte[Long.SIZE / Byte.SIZE]; + out.readBytes(cookieRead); + byte[] cookieMaskRead = new byte[Long.SIZE / Byte.SIZE]; + out.readBytes(cookieMaskRead); + Assert.assertArrayEquals("Wrong metadata", cookie, cookieRead); + Assert.assertArrayEquals("Wrong metadata mask", cookieMask, cookieMaskRead); } - private static FlowModFlags createFlowModFalgsFromBitmap(short input){ + private static FlowModFlags createFlowModFlagsFromBitmap(int input){ final Boolean _oFPFFSENDFLOWREM = (input & (1 << 0)) > 0; final Boolean _oFPFFCHECKOVERLAP = (input & (1 << 1)) > 0; final Boolean _oFPFFRESETCOUNTS = (input & (1 << 2)) > 0; diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PacketOutInputMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PacketOutInputMessageFactoryTest.java index 6e30ae6e..7e78f561 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PacketOutInputMessageFactoryTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PacketOutInputMessageFactoryTest.java @@ -3,11 +3,23 @@ package org.opendaylight.openflowjava.protocol.impl.serialization.factories; import io.netty.buffer.ByteBuf; import io.netty.buffer.UnpooledByteBufAllocator; -import junit.framework.Assert; +import java.util.ArrayList; +import java.util.List; + +import org.junit.Assert; import org.junit.Test; import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.HelloMessageFactoryTest; import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; +import org.opendaylight.openflowjava.protocol.impl.util.ByteBufUtils; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.EthertypeAction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.EthertypeActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PopVlan; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PushVlan; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.ActionsList; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.ActionsListBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.actions.list.ActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.EtherType; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInputBuilder; @@ -18,8 +30,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731 */ public class PacketOutInputMessageFactoryTest { private static final byte MESSAGE_TYPE = 13; - private static final int MESSAGE_LENGTH = 24; private static final byte PADDING_IN_PACKET_OUT_MESSAGE = 6; + private static final int PADDING_IN_ACTION_HEADER = 4; /** * Testing of {@link PacketOutInputMessageFactory} for correct translation from POJO @@ -31,17 +43,39 @@ public class PacketOutInputMessageFactoryTest { BufferHelper.setupHeader(builder); builder.setBufferId(256L); builder.setInPort(new PortNumber(256L)); + List actions = new ArrayList<>(); + ActionsListBuilder actionsListBuilder = new ActionsListBuilder(); + ActionBuilder actionBuilder = new ActionBuilder(); + actionBuilder.setType(PushVlan.class); + EthertypeActionBuilder ethertypeBuilder = new EthertypeActionBuilder(); + ethertypeBuilder.setEthertype(new EtherType(25)); + actionBuilder.addAugmentation(EthertypeAction.class, ethertypeBuilder.build()); + actionsListBuilder.setAction(actionBuilder.build()); + actions.add(actionsListBuilder.build()); + actionBuilder = new ActionBuilder(); + actionBuilder.setType(PopVlan.class); + actionsListBuilder.setAction(actionBuilder.build()); + actions.add(actionsListBuilder.build()); + builder.setActionsList(actions); + builder.setData(ByteBufUtils.hexStringToBytes("00 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14")); PacketOutInput message = builder.build(); ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); PacketOutInputMessageFactory factory = PacketOutInputMessageFactory.getInstance(); factory.messageToBuffer(HelloMessageFactoryTest.VERSION_YET_SUPPORTED, out, message); - BufferHelper.checkHeaderV13(out, MESSAGE_TYPE, MESSAGE_LENGTH); + BufferHelper.checkHeaderV13(out, MESSAGE_TYPE, 56); Assert.assertEquals("Wrong BufferId", message.getBufferId().longValue(), out.readUnsignedInt()); Assert.assertEquals("Wrong PortNumber", message.getInPort().getValue().longValue(), out.readUnsignedInt()); - // TODO make test for actions after its implementation in factory - // TODO data + Assert.assertEquals("Wrong ActionsLength", 16, out.readUnsignedShort()); out.skipBytes(PADDING_IN_PACKET_OUT_MESSAGE); + Assert.assertEquals("Wrong action type", 17, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 8, out.readUnsignedShort()); + Assert.assertEquals("Wrong ethertype", 25, out.readUnsignedShort()); + out.skipBytes(Short.SIZE / Byte.SIZE); + Assert.assertEquals("Wrong action type", 18, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 8, out.readUnsignedShort()); + out.skipBytes(PADDING_IN_ACTION_HEADER); + Assert.assertArrayEquals("Wrong data", message.getData(), out.readBytes(out.readableBytes()).array()); } } -- 2.36.6