2 * Copyright (c) 2013 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.openflowjava.protocol.impl.util;
11 import io.netty.buffer.ByteBuf;
13 import java.util.ArrayList;
14 import java.util.List;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.EthertypeAction;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.EthertypeActionBuilder;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ExperimenterAction;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ExperimenterActionBuilder;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.GroupIdAction;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.GroupIdActionBuilder;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MaxLengthAction;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MaxLengthActionBuilder;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MplsTtlAction;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MplsTtlActionBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.NwTtlAction;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.NwTtlActionBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.OxmFieldsAction;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.OxmFieldsActionBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortAction;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortActionBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.QueueIdAction;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.QueueIdActionBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.CopyTtlIn;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.CopyTtlOut;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.DecMplsTtl;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.DecNwTtl;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.Experimenter;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.Group;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.Output;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PopMpls;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PopPbb;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PopVlan;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PushMpls;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PushPbb;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PushVlan;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetField;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetMplsTtl;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetNwTtl;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetQueue;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.grouping.Action;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.grouping.ActionBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ActionBase;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.EtherType;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber;
58 * Deserializes ofp_actions (OpenFlow v1.3)
59 * @author timotej.kubas
60 * @author michal.polkorab
62 public class ActionsDeserializer {
64 private static final byte ACTION_HEADER_LENGTH = 4;
65 private static final byte PADDING_IN_ACTIONS_HEADER = 4;
66 private static final byte PADDING_IN_OUTPUT_ACTIONS_HEADER = 6;
67 private static final byte PADDING_IN_SET_MPLS_TTL_ACTIONS_HEADER = 3;
68 private static final byte PADDING_IN_PUSH_VLAN_ACTIONS_HEADER = 2;
69 private static final byte PADDING_IN_NW_TTL_ACTIONS_HEADER = 3;
70 private static final byte EXPERIMENTER_ACTION_HEADER_LENGTH = 8;
73 * Creates list of actions (OpenFlow v1.3)
74 * @param input input ByteBuf
75 * @param actionsLength length of buckets
78 public static List<Action> createActions(ByteBuf input, int actionsLength) {
79 List<Action> actions = new ArrayList<>();
81 while (length < actionsLength) {
82 int type = input.readUnsignedShort();
83 int currentActionLength = input.readUnsignedShort();
84 ActionBuilder actionBuilder = new ActionBuilder();
87 actions.add(createOutputAction(input, actionBuilder));
90 actions.add(createCopyTtlOutAction(input, actionBuilder));
93 actions.add(createCopyTtlInAction(input, actionBuilder));
96 actions.add(createSetMplsTtlAction(input, actionBuilder));
99 actions.add(createDecMplsTtlOutAction(input, actionBuilder));
102 actions.add(createPushVlanAction(input, actionBuilder));
105 actions.add(createPopVlanAction(input, actionBuilder));
108 actions.add(createPushMplsAction(input, actionBuilder));
111 actions.add(createPopMplsAction(input, actionBuilder));
114 actions.add(createSetQueueAction(input, actionBuilder));
117 actions.add(createGroupAction(input, actionBuilder));
120 actions.add(createSetNwTtlAction(input, actionBuilder));
123 actions.add(createDecNwTtlAction(input, actionBuilder));
126 actions.add(createSetFieldAction(input, actionBuilder, currentActionLength));
129 actions.add(createPushPbbAction(input, actionBuilder));
132 actions.add(createPopPbbAction(input, actionBuilder));
135 actions.add(createExperimenterAction(input, actionBuilder, currentActionLength));
140 length += currentActionLength;
146 * Creates action ids - actions without values (OpenFlow v1.3)
147 * @param input input ByteBuf
148 * @param actionsLength length of actions
149 * @return ActionsList
151 public static List<Action> createActionIds(ByteBuf input, int actionsLength) {
152 List<Action> actionsList = new ArrayList<>();
154 ActionBuilder builder;
155 while (length < actionsLength) {
156 builder = new ActionBuilder();
157 int type = input.readUnsignedShort();
158 int currentActionLength = input.readUnsignedShort();
161 builder.setType(Output.class);
164 builder.setType(CopyTtlOut.class);
167 builder.setType(CopyTtlIn.class);
170 builder.setType(SetMplsTtl.class);
173 builder.setType(DecMplsTtl.class);
176 builder.setType(PushVlan.class);
179 builder.setType(PopVlan.class);
182 builder.setType(PushMpls.class);
185 builder.setType(PopMpls.class);
188 builder.setType(SetQueue.class);
191 builder.setType(Group.class);
194 builder.setType(SetNwTtl.class);
197 builder.setType(DecNwTtl.class);
200 builder.setType(SetField.class);
203 builder.setType(PushPbb.class);
206 builder.setType(PopPbb.class);
209 builder.setType(Experimenter.class);
210 ExperimenterActionBuilder experimenter = new ExperimenterActionBuilder();
211 experimenter.setExperimenter(input.readUnsignedInt());
212 builder.addAugmentation(ExperimenterAction.class, experimenter.build());
217 actionsList.add(builder.build());
218 length += currentActionLength;
223 private static Action createEmptyHeader(Class<? extends ActionBase> action,
224 ByteBuf in, ActionBuilder actionBuilder) {
225 actionBuilder.setType(action);
226 in.skipBytes(PADDING_IN_ACTIONS_HEADER);
227 return actionBuilder.build();
230 private static Action createCopyTtlInAction(ByteBuf in, ActionBuilder actionBuilder) {
231 return createEmptyHeader(CopyTtlIn.class, in, actionBuilder);
234 private static Action createCopyTtlOutAction(ByteBuf in, ActionBuilder actionBuilder) {
235 return createEmptyHeader(CopyTtlOut.class, in, actionBuilder);
238 private static Action createDecMplsTtlOutAction(ByteBuf in, ActionBuilder actionBuilder) {
239 return createEmptyHeader(DecMplsTtl.class, in, actionBuilder);
242 private static Action createPopVlanAction(ByteBuf in, ActionBuilder actionBuilder) {
243 return createEmptyHeader(PopVlan.class, in, actionBuilder);
246 private static Action createDecNwTtlAction(ByteBuf in, ActionBuilder actionBuilder) {
247 return createEmptyHeader(DecNwTtl.class, in, actionBuilder);
250 private static Action createPopPbbAction(ByteBuf in, ActionBuilder actionBuilder) {
251 return createEmptyHeader(PopPbb.class, in, actionBuilder);
254 private static Action createOutputAction(ByteBuf in, ActionBuilder actionBuilder) {
255 actionBuilder.setType(Output.class);
256 PortActionBuilder port = new PortActionBuilder();
257 port.setPort(new PortNumber(in.readUnsignedInt()));
258 actionBuilder.addAugmentation(PortAction.class, port.build());
259 MaxLengthActionBuilder maxLen = new MaxLengthActionBuilder();
260 maxLen.setMaxLength(in.readUnsignedShort());
261 actionBuilder.addAugmentation(MaxLengthAction.class, maxLen.build());
262 in.skipBytes(PADDING_IN_OUTPUT_ACTIONS_HEADER);
263 return actionBuilder.build();
266 private static Action createSetMplsTtlAction(ByteBuf in, ActionBuilder actionBuilder) {
267 actionBuilder.setType(SetMplsTtl.class);
268 MplsTtlActionBuilder mplsTtl = new MplsTtlActionBuilder();
269 mplsTtl.setMplsTtl(in.readUnsignedByte());
270 actionBuilder.addAugmentation(MplsTtlAction.class, mplsTtl.build());
271 in.skipBytes(PADDING_IN_SET_MPLS_TTL_ACTIONS_HEADER);
272 return actionBuilder.build();
275 private static Action createPushAction(Class<? extends ActionBase> action,
276 ByteBuf in, ActionBuilder actionBuilder) {
277 actionBuilder.setType(action);
278 EthertypeActionBuilder etherType = new EthertypeActionBuilder();
279 etherType.setEthertype(new EtherType(in.readUnsignedShort()));
280 actionBuilder.addAugmentation(EthertypeAction.class, etherType.build());
281 in.skipBytes(PADDING_IN_PUSH_VLAN_ACTIONS_HEADER);
282 return actionBuilder.build();
285 private static Action createPushVlanAction(ByteBuf in, ActionBuilder actionBuilder) {
286 return createPushAction(PushVlan.class, in, actionBuilder);
289 private static Action createPushMplsAction(ByteBuf in, ActionBuilder actionBuilder) {
290 return createPushAction(PushMpls.class, in, actionBuilder);
293 private static Action createPopMplsAction(ByteBuf in, ActionBuilder actionBuilder) {
294 return createPushAction(PopMpls.class, in, actionBuilder);
297 private static Action createPushPbbAction(ByteBuf in, ActionBuilder actionBuilder) {
298 return createPushAction(PushPbb.class, in, actionBuilder);
301 private static Action createSetQueueAction(ByteBuf in, ActionBuilder actionBuilder) {
302 actionBuilder.setType(SetQueue.class);
303 QueueIdActionBuilder queueId = new QueueIdActionBuilder();
304 queueId.setQueueId(in.readUnsignedInt());
305 actionBuilder.addAugmentation(QueueIdAction.class, queueId.build());
306 return actionBuilder.build();
309 private static Action createGroupAction(ByteBuf in, ActionBuilder actionBuilder) {
310 actionBuilder.setType(Group.class);
311 GroupIdActionBuilder group = new GroupIdActionBuilder();
312 group.setGroupId(in.readUnsignedInt());
313 actionBuilder.addAugmentation(GroupIdAction.class, group.build());
314 return actionBuilder.build();
317 private static Action createExperimenterAction(ByteBuf in, ActionBuilder actionBuilder, int actionLength) {
318 actionBuilder.setType(Experimenter.class);
319 ExperimenterActionBuilder experimenter = new ExperimenterActionBuilder();
320 experimenter.setExperimenter(in.readUnsignedInt());
321 int dataLength = actionLength - EXPERIMENTER_ACTION_HEADER_LENGTH;
322 if (dataLength > 0) {
323 byte[] data = new byte[dataLength];
325 experimenter.setData(data);
327 actionBuilder.addAugmentation(ExperimenterAction.class, experimenter.build());
328 return actionBuilder.build();
331 private static Action createSetNwTtlAction(ByteBuf in, ActionBuilder actionBuilder) {
332 actionBuilder.setType(SetNwTtl.class);
333 NwTtlActionBuilder nwTtl = new NwTtlActionBuilder();
334 nwTtl.setNwTtl(in.readUnsignedByte());
335 actionBuilder.addAugmentation(NwTtlAction.class, nwTtl.build());
336 in.skipBytes(PADDING_IN_NW_TTL_ACTIONS_HEADER);
337 return actionBuilder.build();
340 private static Action createSetFieldAction(ByteBuf in, ActionBuilder actionBuilder, int actionLength) {
341 actionBuilder.setType(SetField.class);
342 OxmFieldsActionBuilder matchEntries = new OxmFieldsActionBuilder();
343 matchEntries.setMatchEntries(MatchDeserializer.createMatchEntry(in, actionLength - ACTION_HEADER_LENGTH));
344 actionBuilder.addAugmentation(OxmFieldsAction.class, matchEntries.build());
345 return actionBuilder.build();