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.ActionsList;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.ActionsListBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.actions.list.ActionBuilder;
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 abstract 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;
72 * Creates list of actions (OpenFlow v1.3)
73 * @param input input ByteBuf
74 * @param actionsLength length of buckets
77 public static List<ActionsList> createActionsList(ByteBuf input, int actionsLength) {
78 ActionsListBuilder actionsListBuilder = new ActionsListBuilder();
79 List<ActionsList> actionsList = new ArrayList<>();
81 while (length < actionsLength) {
82 int currentActionLength = 0;
83 switch(input.readUnsignedShort()) {
84 case 0: currentActionLength = input.readUnsignedShort(); //outputActionLength
85 actionsList.add(createOutputAction(input, actionsListBuilder));
88 currentActionLength = input.readUnsignedShort();//empty header length
89 actionsList.add(createCopyTtlOutAction(input, actionsListBuilder));
93 currentActionLength = input.readUnsignedShort();//empty header length
94 actionsList.add(createCopyTtlInAction(input, actionsListBuilder));
98 currentActionLength = input.readUnsignedShort();//empty header length
99 actionsList.add(createSetMplsTtlAction(input, actionsListBuilder));
103 currentActionLength = input.readUnsignedShort();//empty header length
104 actionsList.add(createDecMplsTtlOutAction(input, actionsListBuilder));
108 currentActionLength = input.readUnsignedShort();
109 actionsList.add(createPushVlanAction(input, actionsListBuilder));
113 currentActionLength = input.readUnsignedShort();//empty header length
114 actionsList.add(createPopVlanAction(input, actionsListBuilder));
118 currentActionLength = input.readUnsignedShort();//8
119 actionsList.add(createPushMplsAction(input, actionsListBuilder));
123 currentActionLength = input.readUnsignedShort();//8
124 actionsList.add(createPopMplsAction(input, actionsListBuilder));
128 currentActionLength = input.readUnsignedShort();
129 actionsList.add(createSetQueueAction(input, actionsListBuilder));
133 currentActionLength = input.readUnsignedShort();//8
134 actionsList.add(createGroupAction(input, actionsListBuilder));
138 currentActionLength = input.readUnsignedShort();//8
139 actionsList.add(createSetNwTtlAction(input, actionsListBuilder));
143 currentActionLength = input.readUnsignedShort();//empty header length
144 actionsList.add(createDecNwTtlAction(input, actionsListBuilder));
148 currentActionLength = input.readUnsignedShort();//8
149 actionsList.add(createSetFieldAction(input, actionsListBuilder, currentActionLength));
152 currentActionLength = input.readUnsignedShort();//8
153 actionsList.add(createPushPbbAction(input, actionsListBuilder));
157 currentActionLength = input.readUnsignedShort();//empty header length
158 actionsList.add(createPopPbbAction(input, actionsListBuilder));
162 currentActionLength = input.readUnsignedShort();
163 actionsList.add(createExperimenterAction(input, actionsListBuilder));
168 length += currentActionLength;
173 private static ActionsList createEmptyHeader(Class<? extends org.opendaylight.yang.gen.v1.
174 urn.opendaylight.openflow.common.types.rev130731.Action> action,
175 ByteBuf in, ActionsListBuilder actionsListBuilder) {
176 ActionBuilder actionBuilder = new ActionBuilder();
177 actionBuilder.setType(action);
178 in.skipBytes(PADDING_IN_ACTIONS_HEADER);
179 actionsListBuilder.setAction(actionBuilder.build());
180 return actionsListBuilder.build();
183 private static ActionsList createCopyTtlInAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {
184 return createEmptyHeader(CopyTtlIn.class, in, actionsListBuilder);
187 private static ActionsList createCopyTtlOutAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {
188 return createEmptyHeader(CopyTtlOut.class, in, actionsListBuilder);
191 private static ActionsList createDecMplsTtlOutAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {
192 return createEmptyHeader(DecMplsTtl.class, in, actionsListBuilder);
195 private static ActionsList createPopVlanAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {
196 return createEmptyHeader(PopVlan.class, in, actionsListBuilder);
199 private static ActionsList createDecNwTtlAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {
200 return createEmptyHeader(DecNwTtl.class, in, actionsListBuilder);
203 private static ActionsList createPopPbbAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {
204 return createEmptyHeader(PopPbb.class, in, actionsListBuilder);
207 private static ActionsList createOutputAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {
208 ActionBuilder actionBuilder = new ActionBuilder();
209 actionBuilder.setType(Output.class);
210 PortActionBuilder port = new PortActionBuilder();
211 port.setPort(new PortNumber(in.readUnsignedInt()));
212 actionBuilder.addAugmentation(PortAction.class, port.build());
213 MaxLengthActionBuilder maxLen = new MaxLengthActionBuilder();
214 maxLen.setMaxLength(in.readUnsignedShort());
215 actionBuilder.addAugmentation(MaxLengthAction.class, maxLen.build());
216 actionsListBuilder.setAction(actionBuilder.build());
217 in.skipBytes(PADDING_IN_OUTPUT_ACTIONS_HEADER);
218 return actionsListBuilder.build();
221 private static ActionsList createSetMplsTtlAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {
222 ActionBuilder actionBuilder = new ActionBuilder();
223 actionBuilder.setType(SetMplsTtl.class);
224 MplsTtlActionBuilder mplsTtl = new MplsTtlActionBuilder();
225 mplsTtl.setMplsTtl(in.readUnsignedByte());
226 actionBuilder.addAugmentation(MplsTtlAction.class, mplsTtl.build());
227 actionsListBuilder.setAction(actionBuilder.build());
228 in.skipBytes(PADDING_IN_SET_MPLS_TTL_ACTIONS_HEADER);
229 return actionsListBuilder.build();
232 private static ActionsList createPushAction(Class<? extends org.opendaylight.yang.gen.
233 v1.urn.opendaylight.openflow.common.types.rev130731.Action> action,
234 ByteBuf in, ActionsListBuilder actionsListBuilder) {
235 ActionBuilder actionBuilder = new ActionBuilder();
236 actionBuilder.setType(action);
237 EthertypeActionBuilder etherType = new EthertypeActionBuilder();
238 etherType.setEthertype(new EtherType(in.readUnsignedShort()));
239 actionBuilder.addAugmentation(EthertypeAction.class, etherType.build());
240 actionsListBuilder.setAction(actionBuilder.build());
241 in.skipBytes(PADDING_IN_PUSH_VLAN_ACTIONS_HEADER);
242 return actionsListBuilder.build();
245 private static ActionsList createPushVlanAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {
246 return createPushAction(PushVlan.class, in, actionsListBuilder);
249 private static ActionsList createPushMplsAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {
250 return createPushAction(PushMpls.class, in, actionsListBuilder);
253 private static ActionsList createPopMplsAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {
254 return createPushAction(PopMpls.class, in, actionsListBuilder);
257 private static ActionsList createPushPbbAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {
258 return createPushAction(PushPbb.class, in, actionsListBuilder);
261 private static ActionsList createSetQueueAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {
262 ActionBuilder actionBuilder = new ActionBuilder();
263 actionBuilder.setType(SetQueue.class);
264 QueueIdActionBuilder queueId = new QueueIdActionBuilder();
265 queueId.setQueueId(in.readUnsignedInt());
266 actionBuilder.addAugmentation(QueueIdAction.class, queueId.build());
267 actionsListBuilder.setAction(actionBuilder.build());
268 return actionsListBuilder.build();
271 private static ActionsList createGroupAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {
272 ActionBuilder actionBuilder = new ActionBuilder();
273 actionBuilder.setType(Group.class);
274 GroupIdActionBuilder group = new GroupIdActionBuilder();
275 group.setGroupId(in.readUnsignedInt());
276 actionBuilder.addAugmentation(GroupIdAction.class, group.build());
277 actionsListBuilder.setAction(actionBuilder.build());
278 return actionsListBuilder.build();
281 private static ActionsList createExperimenterAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {
282 ActionBuilder actionBuilder = new ActionBuilder();
283 actionBuilder.setType(Experimenter.class);
284 ExperimenterActionBuilder experimenter = new ExperimenterActionBuilder();
285 experimenter.setExperimenter(in.readUnsignedInt());
286 actionBuilder.addAugmentation(ExperimenterAction.class, experimenter.build());
287 actionsListBuilder.setAction(actionBuilder.build());
288 return actionsListBuilder.build();
291 private static ActionsList createSetNwTtlAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {
292 ActionBuilder actionBuilder = new ActionBuilder();
293 actionBuilder.setType(SetNwTtl.class);
294 NwTtlActionBuilder nwTtl = new NwTtlActionBuilder();
295 nwTtl.setNwTtl(in.readUnsignedByte());
296 actionBuilder.addAugmentation(NwTtlAction.class, nwTtl.build());
297 actionsListBuilder.setAction(actionBuilder.build());
298 in.skipBytes(PADDING_IN_NW_TTL_ACTIONS_HEADER);
299 return actionsListBuilder.build();
302 private static ActionsList createSetFieldAction(ByteBuf in, ActionsListBuilder actionsListBuilder, int actionLength) {
303 ActionBuilder actionBuilder = new ActionBuilder();
304 actionBuilder.setType(SetField.class);
305 OxmFieldsActionBuilder matchEntries = new OxmFieldsActionBuilder();
306 matchEntries.setMatchEntries(MatchDeserializer.createMatchEntry(in, actionLength - ACTION_HEADER_LENGTH));
307 actionBuilder.addAugmentation(OxmFieldsAction.class, matchEntries.build());
308 actionsListBuilder.setAction(actionBuilder.build());
309 return actionsListBuilder.build();