X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=openflow-protocol-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fopenflowjava%2Fprotocol%2Fimpl%2Futil%2FInstructionsSerializer.java;h=80ce60d74662c286c89b83381376927275f94960;hb=8dbddef7a44dc651fcec2c47e7c1e67b6078acb8;hp=aa998bcabe02aaad6b84adcfab69907e7eb675cc;hpb=09a089ee658f6fc1627b5eafdbb29249e7c7ffb9;p=openflowjava.git diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/InstructionsSerializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/InstructionsSerializer.java index aa998bca..80ce60d7 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/InstructionsSerializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/InstructionsSerializer.java @@ -1,143 +1,185 @@ -/* Copyright (C)2013 Pantheon Technologies, s.r.o. All rights reserved. */ -package org.opendaylight.openflowjava.protocol.impl.util; - -import io.netty.buffer.ByteBuf; - -import java.util.List; - -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ActionsInstruction; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ExperimenterInstruction; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MetadataInstruction; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MeterIdInstruction; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.TableIdInstruction; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.ActionsList; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.ApplyActions; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.ClearActions; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.Experimenter; -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.Meter; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.WriteActions; -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.types.rev130731.Instruction; - -/** - * Serializes ofp_instruction (OpenFlow v 1.3) structure - * @author michal.polkorab - * @author timotej.kubas - */ -public abstract class InstructionsSerializer { - - /** - * Encodes instructions - * @param instructions List of instructions - * @param out output buffer - */ - public static void encodeInstructions(List instructions, ByteBuf out) { - if (instructions != null) { - for (Instructions instruction : instructions) { - Class type = instruction.getType(); - if (type.equals(GotoTable.class)) { - final byte GOTO_TABLE_TYPE = 1; - final byte GOTO_TABLE_LENGTH = 8; - final byte PADDING_IN_GOTO_TABLE = 3; - writeTypeAndLength(out, GOTO_TABLE_TYPE, GOTO_TABLE_LENGTH); - out.writeByte(instruction.getAugmentation(TableIdInstruction.class).getTableId()); - ByteBufUtils.padBuffer(PADDING_IN_GOTO_TABLE, out); - } else if (type.equals(WriteMetadata.class)) { - final byte WRITE_METADATA_TYPE = 2; - final byte WRITE_METADATA_LENGTH = 24; - final byte PADDING_IN_WRITE_METADATA = 4; - writeTypeAndLength(out, WRITE_METADATA_TYPE, WRITE_METADATA_LENGTH); - ByteBufUtils.padBuffer(PADDING_IN_WRITE_METADATA, out); - MetadataInstruction metadata = instruction.getAugmentation(MetadataInstruction.class); - out.writeBytes(metadata.getMetadata()); - out.writeBytes(metadata.getMetadataMask()); - } else if (type.equals(WriteActions.class)) { - final byte WRITE_ACTIONS_TYPE = 3; - writeActionsInstruction(out, instruction, WRITE_ACTIONS_TYPE); - } else if (type.equals(ApplyActions.class)) { - final byte APPLY_ACTIONS_TYPE = 4; - writeActionsInstruction(out, instruction, APPLY_ACTIONS_TYPE); - } else if (type.equals(ClearActions.class)) { - final byte CLEAR_ACTIONS_TYPE = 5; - final byte CLEAR_ACTIONS_LENGTH = 8; - final byte PADDING_IN_CLEAR_ACTIONS = 4; - writeTypeAndLength(out, CLEAR_ACTIONS_TYPE, CLEAR_ACTIONS_LENGTH); - ByteBufUtils.padBuffer(PADDING_IN_CLEAR_ACTIONS, out); - } else if (type.equals(Meter.class)) { - final byte METER_TYPE = 6; - final byte METER_LENGTH = 8; - writeTypeAndLength(out, METER_TYPE, METER_LENGTH); - out.writeInt(instruction.getAugmentation(MeterIdInstruction.class).getMeterId().intValue()); - } else if (type.equals(Experimenter.class)) { - final byte EXPERIMENTER_TYPE = 7; - final byte EXPERIMENTER_LENGTH = 8; - ExperimenterInstruction experimenter = instruction.getAugmentation(ExperimenterInstruction.class); - byte[] data = experimenter.getData(); - writeTypeAndLength(out, EXPERIMENTER_TYPE, EXPERIMENTER_LENGTH + data.length); - out.writeInt(experimenter.getExperimenter().intValue()); - out.writeBytes(data); - } - } - } - - } - - private static void writeTypeAndLength(ByteBuf out, int type, int length) { - out.writeShort(type); - out.writeShort(length); - } - - private static void writeActionsInstruction(ByteBuf out, - Instructions instruction, int type) { - final byte ACTIONS_INSTRUCTION_LENGTH = 8; - final byte PADDING_IN_ACTIONS_INSTRUCTION = 4; - out.writeShort(type); - List actions = instruction.getAugmentation(ActionsInstruction.class).getActionsList(); - out.writeShort(ACTIONS_INSTRUCTION_LENGTH + ActionsSerializer.computeLengthOfActions(actions)); - ByteBufUtils.padBuffer(PADDING_IN_ACTIONS_INSTRUCTION, out); - ActionsSerializer.encodeActions(actions, out); - } - - /** - * Computes length of instructions - * @param instructions List of instructions - * @return length of instructions (in bytes) - */ - public static int computeInstructionsLength(List instructions) { - int length = 0; - if (instructions != null) { - for (Instructions instruction : instructions) { - Class type = instruction.getType(); - if (type.equals(GotoTable.class)) { - final byte GOTO_TABLE_LENGTH = 8; - length += GOTO_TABLE_LENGTH; - } else if (type.equals(WriteMetadata.class)) { - final byte WRITE_METADATA_LENGTH = 24; - length += WRITE_METADATA_LENGTH; - } else if (type.equals(WriteActions.class)) { - final byte WRITE_ACTIONS_LENGTH = 8; - length += WRITE_ACTIONS_LENGTH + ActionsSerializer.computeLengthOfActions( - instruction.getAugmentation(ActionsInstruction.class).getActionsList()); - } else if (type.equals(ApplyActions.class)) { - final byte APPLY_ACTIONS_LENGTH = 8; - length += APPLY_ACTIONS_LENGTH + ActionsSerializer.computeLengthOfActions( - instruction.getAugmentation(ActionsInstruction.class).getActionsList()); - } else if (type.equals(ClearActions.class)) { - final byte CLEAR_ACTIONS_LENGTH = 8; - length += CLEAR_ACTIONS_LENGTH; - } else if (type.equals(Meter.class)) { - final byte METER_LENGTH = 8; - length += METER_LENGTH; - } else if (type.equals(Experimenter.class)) { - final byte EXPERIMENTER_LENGTH = 8; - ExperimenterInstruction experimenter = instruction.getAugmentation(ExperimenterInstruction.class); - byte[] data = experimenter.getData(); - length += EXPERIMENTER_LENGTH + data.length; - } - } - } - return length; - } -} +/* + * Copyright (c) 2013 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.util; + +import io.netty.buffer.ByteBuf; + +import java.util.List; + +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ActionsInstruction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ExperimenterInstruction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MetadataInstruction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MeterIdInstruction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.TableIdInstruction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.ActionsList; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.ApplyActions; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.ClearActions; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.Experimenter; +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.Meter; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.WriteActions; +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.types.rev130731.Instruction; + +/** + * Serializes ofp_instruction (OpenFlow v 1.3) structure + * @author michal.polkorab + * @author timotej.kubas + */ +public abstract class InstructionsSerializer { + + private static final byte GOTO_TABLE_TYPE = 1; + private static final byte WRITE_METADATA_TYPE = 2; + private static final byte WRITE_ACTIONS_TYPE = 3; + private static final byte APPLY_ACTIONS_TYPE = 4; + private static final byte CLEAR_ACTIONS_TYPE = 5; + private static final byte METER_TYPE = 6; + private static final byte EXPERIMENTER_TYPE = 7; + private static final byte GOTO_TABLE_LENGTH = 8; + private static final byte WRITE_METADATA_LENGTH = 24; + private static final byte METER_LENGTH = 8; + private static final byte EXPERIMENTER_LENGTH = 8; + private static final byte ACTIONS_INSTRUCTION_LENGTH = 8; + private static final byte PADDING_IN_GOTO_TABLE = 3; + private static final byte PADDING_IN_WRITE_METADATA = 4; + private static final byte PADDING_IN_CLEAR_ACTIONS = 4; + private static final byte INSTRUCTION_IDS_LENGTH = 4; + private static final byte PADDING_IN_ACTIONS_INSTRUCTION = 4; + + /** + * Encodes instructions + * @param instructions List of instructions + * @param out output buffer + */ + public static void encodeInstructions(List instructions, ByteBuf out) { + if (instructions != null) { + for (Instructions instruction : instructions) { + Class type = instruction.getType(); + if (type.isAssignableFrom(GotoTable.class)) { + writeTypeAndLength(out, GOTO_TABLE_TYPE, GOTO_TABLE_LENGTH); + out.writeByte(instruction.getAugmentation(TableIdInstruction.class).getTableId()); + ByteBufUtils.padBuffer(PADDING_IN_GOTO_TABLE, out); + } else if (type.isAssignableFrom(WriteMetadata.class)) { + writeTypeAndLength(out, WRITE_METADATA_TYPE, WRITE_METADATA_LENGTH); + ByteBufUtils.padBuffer(PADDING_IN_WRITE_METADATA, out); + MetadataInstruction metadata = instruction.getAugmentation(MetadataInstruction.class); + out.writeBytes(metadata.getMetadata()); + out.writeBytes(metadata.getMetadataMask()); + } else if (type.isAssignableFrom(WriteActions.class)) { + writeActionsInstruction(out, instruction, WRITE_ACTIONS_TYPE); + } else if (type.isAssignableFrom(ApplyActions.class)) { + writeActionsInstruction(out, instruction, APPLY_ACTIONS_TYPE); + } else if (type.isAssignableFrom(ClearActions.class)) { + writeTypeAndLength(out, CLEAR_ACTIONS_TYPE, ACTIONS_INSTRUCTION_LENGTH); + ByteBufUtils.padBuffer(PADDING_IN_CLEAR_ACTIONS, out); + } else if (type.isAssignableFrom(Meter.class)) { + writeTypeAndLength(out, METER_TYPE, METER_LENGTH); + out.writeInt(instruction.getAugmentation(MeterIdInstruction.class).getMeterId().intValue()); + } else if (type.isAssignableFrom(Experimenter.class)) { + ExperimenterInstruction experimenter = instruction.getAugmentation(ExperimenterInstruction.class); + byte[] data = experimenter.getData(); + writeTypeAndLength(out, EXPERIMENTER_TYPE, EXPERIMENTER_LENGTH + data.length); + out.writeInt(experimenter.getExperimenter().intValue()); + out.writeBytes(data); + } + } + } + + } + + /** + * Encodes instruction ids (for Multipart - TableFeatures messages) + * @param instructions List of instruction identifiers (without values) + * @param out output buffer + */ + public static void encodeInstructionIds(List instructions, ByteBuf out) { + if (instructions != null) { + for (Instructions instruction : instructions) { + Class type = instruction.getType(); + if (type.isAssignableFrom(GotoTable.class)) { + writeTypeAndLength(out, GOTO_TABLE_TYPE, INSTRUCTION_IDS_LENGTH); + } else if (type.isAssignableFrom(WriteMetadata.class)) { + writeTypeAndLength(out, WRITE_METADATA_TYPE, INSTRUCTION_IDS_LENGTH); + } else if (type.isAssignableFrom(WriteActions.class)) { + writeTypeAndLength(out, WRITE_ACTIONS_TYPE, INSTRUCTION_IDS_LENGTH); + } else if (type.isAssignableFrom(ApplyActions.class)) { + writeTypeAndLength(out, APPLY_ACTIONS_TYPE, INSTRUCTION_IDS_LENGTH); + } else if (type.isAssignableFrom(ClearActions.class)) { + writeTypeAndLength(out, CLEAR_ACTIONS_TYPE, INSTRUCTION_IDS_LENGTH); + } else if (type.isAssignableFrom(Meter.class)) { + writeTypeAndLength(out, METER_TYPE, INSTRUCTION_IDS_LENGTH); + } else if (type.isAssignableFrom(Experimenter.class)) { + ExperimenterInstruction experimenter = instruction.getAugmentation(ExperimenterInstruction.class); + writeTypeAndLength(out, EXPERIMENTER_TYPE, EncodeConstants.EXPERIMENTER_IDS_LENGTH); + out.writeInt(experimenter.getExperimenter().intValue()); + } + } + } + } + + private static void writeTypeAndLength(ByteBuf out, int type, int length) { + out.writeShort(type); + out.writeShort(length); + } + + private static void writeActionsInstruction(ByteBuf out, + Instructions instruction, int type) { + out.writeShort(type); + if (instruction.getAugmentation(ActionsInstruction.class) != null) { + List actions = instruction.getAugmentation(ActionsInstruction.class).getActionsList(); + out.writeShort(ACTIONS_INSTRUCTION_LENGTH + ActionsSerializer.computeLengthOfActions(actions)); + ByteBufUtils.padBuffer(PADDING_IN_ACTIONS_INSTRUCTION, out); + ActionsSerializer.encodeActions(actions, out); + } else { + out.writeShort(ACTIONS_INSTRUCTION_LENGTH); + ByteBufUtils.padBuffer(PADDING_IN_ACTIONS_INSTRUCTION, out); + } + } + + /** + * Computes length of instructions + * @param instructions List of instructions + * @return length of instructions (in bytes) + */ + public static int computeInstructionsLength(List instructions) { + int length = 0; + if (instructions != null) { + for (Instructions instruction : instructions) { + Class type = instruction.getType(); + if (type.isAssignableFrom(GotoTable.class)) { + length += GOTO_TABLE_LENGTH; + } else if (type.isAssignableFrom(WriteMetadata.class)) { + length += WRITE_METADATA_LENGTH; + } else if (type.isAssignableFrom(WriteActions.class)) { + length += ACTIONS_INSTRUCTION_LENGTH; + if (instruction.getAugmentation(ActionsInstruction.class) != null) { + length += ActionsSerializer.computeLengthOfActions( + instruction.getAugmentation(ActionsInstruction.class).getActionsList()); + } + } else if (type.isAssignableFrom(ApplyActions.class)) { + length += ACTIONS_INSTRUCTION_LENGTH; + if (instruction.getAugmentation(ActionsInstruction.class) != null) { + length += ActionsSerializer.computeLengthOfActions( + instruction.getAugmentation(ActionsInstruction.class).getActionsList()); + } + } else if (type.isAssignableFrom(ClearActions.class)) { + length += ACTIONS_INSTRUCTION_LENGTH; + } else if (type.isAssignableFrom(Meter.class)) { + length += METER_LENGTH; + } else if (type.isAssignableFrom(Experimenter.class)) { + ExperimenterInstruction experimenter = instruction.getAugmentation(ExperimenterInstruction.class); + byte[] data = experimenter.getData(); + length += EXPERIMENTER_LENGTH + data.length; + } + } + } + return length; + } +}