2 * Copyright (c) 2016 Pantheon Technologies s.r.o. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.openflowplugin.impl.protocol.deserialization.messages;
11 import com.google.common.base.Preconditions;
12 import io.netty.buffer.ByteBuf;
13 import java.math.BigInteger;
14 import java.util.ArrayList;
15 import java.util.List;
16 import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry;
17 import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistryInjector;
18 import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer;
19 import org.opendaylight.openflowjava.protocol.api.keys.MessageCodeKey;
20 import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
21 import org.opendaylight.openflowjava.protocol.impl.util.InstructionConstants;
22 import org.opendaylight.openflowplugin.api.openflow.protocol.deserialization.MessageCodeExperimenterKey;
23 import org.opendaylight.openflowplugin.extension.api.path.ActionPath;
24 import org.opendaylight.openflowplugin.extension.api.path.MatchPath;
25 import org.opendaylight.openflowplugin.impl.protocol.deserialization.key.MessageCodeActionExperimenterKey;
26 import org.opendaylight.openflowplugin.impl.protocol.deserialization.key.MessageCodeMatchKey;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowMessage;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowMessageBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowModFlags;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.Match;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModCommand;
39 public class FlowMessageDeserializer implements OFDeserializer<FlowMessage>, DeserializerRegistryInjector {
41 private static final byte PADDING = 2;
43 private static final MessageCodeKey MATCH_KEY = new MessageCodeMatchKey(EncodeConstants.OF13_VERSION_ID,
44 EncodeConstants.EMPTY_VALUE, Match.class,
45 MatchPath.FLOWS_STATISTICS_UPDATE_MATCH);
47 private DeserializerRegistry registry;
50 @SuppressWarnings("checkstyle:LineLength")
51 public FlowMessage deserialize(ByteBuf message) {
52 final FlowMessageBuilder builder = new FlowMessageBuilder()
53 .setVersion((short) EncodeConstants.OF13_VERSION_ID)
54 .setXid(message.readUnsignedInt())
55 .setCookie(new FlowCookie(BigInteger.valueOf(message.readLong())))
56 .setCookieMask(new FlowCookie(BigInteger.valueOf(message.readLong())))
57 .setTableId(message.readUnsignedByte())
58 .setCommand(FlowModCommand.forValue(message.readUnsignedByte()))
59 .setIdleTimeout(message.readUnsignedShort())
60 .setHardTimeout(message.readUnsignedShort())
61 .setPriority(message.readUnsignedShort())
62 .setBufferId(message.readUnsignedInt())
63 .setOutPort(BigInteger.valueOf(message.readUnsignedInt()))
64 .setOutGroup(message.readUnsignedInt())
65 .setFlags(createFlowModFlagsFromBitmap(message.readUnsignedShort()));
67 message.skipBytes(PADDING);
69 final OFDeserializer<Match> matchDeserializer = Preconditions.checkNotNull(registry).getDeserializer(MATCH_KEY);
70 builder.setMatch(new MatchBuilder(matchDeserializer.deserialize(message)).build());
72 final int length = message.readableBytes();
75 final List<org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list
76 .Instruction> instructions = new ArrayList<>();
77 final int startIndex = message.readerIndex();
80 while (message.readerIndex() - startIndex < length) {
81 final int type = message.getUnsignedShort(message.readerIndex());
82 OFDeserializer<Instruction> deserializer = null;
84 if (InstructionConstants.APPLY_ACTIONS_TYPE == type) {
85 deserializer = Preconditions.checkNotNull(registry).getDeserializer(
86 new MessageCodeActionExperimenterKey(
87 EncodeConstants.OF13_VERSION_ID, type, Instruction.class,
88 ActionPath.INVENTORY_FLOWNODE_TABLE_APPLY_ACTIONS,
90 } else if (InstructionConstants.WRITE_ACTIONS_TYPE == type) {
91 deserializer = Preconditions.checkNotNull(registry).getDeserializer(
92 new MessageCodeActionExperimenterKey(
93 EncodeConstants.OF13_VERSION_ID, type, Instruction.class,
94 ActionPath.INVENTORY_FLOWNODE_TABLE_WRITE_ACTIONS,
99 if (EncodeConstants.EXPERIMENTER_VALUE == type) {
100 expId = message.getUnsignedInt(message.readerIndex()
101 + 2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES);
104 deserializer = Preconditions.checkNotNull(registry).getDeserializer(
105 new MessageCodeExperimenterKey(
106 EncodeConstants.OF13_VERSION_ID, type, Instruction.class, expId));
109 instructions.add(new InstructionBuilder()
110 .withKey(new InstructionKey(offset))
112 .setInstruction(deserializer.deserialize(message))
118 builder.setInstructions(new InstructionsBuilder()
119 .setInstruction(instructions)
123 return builder.build();
126 private static FlowModFlags createFlowModFlagsFromBitmap(int input) {
127 final Boolean ofp_FF_SendFlowRem = (input & 1 << 0) != 0;
128 final Boolean ofp_FF_CheckOverlap = (input & 1 << 1) != 0;
129 final Boolean ofp_FF_ResetCounts = (input & 1 << 2) != 0;
130 final Boolean ofp_FF_NoPktCounts = (input & 1 << 3) != 0;
131 final Boolean ofp_FF_NoBytCounts = (input & 1 << 4) != 0;
132 return new FlowModFlags(ofp_FF_CheckOverlap, ofp_FF_NoBytCounts, ofp_FF_NoPktCounts, ofp_FF_ResetCounts,
137 public void injectDeserializerRegistry(DeserializerRegistry deserializerRegistry) {
138 registry = deserializerRegistry;