1 /* Copyright (C)2013 Pantheon Technologies, s.r.o. All rights reserved. */
\r
2 package org.opendaylight.openflowjava.protocol.impl.util;
\r
4 import io.netty.buffer.ByteBuf;
\r
6 import java.util.ArrayList;
\r
7 import java.util.List;
\r
9 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.EthertypeAction;
\r
10 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.EthertypeActionBuilder;
\r
11 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ExperimenterAction;
\r
12 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ExperimenterActionBuilder;
\r
13 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.GroupIdAction;
\r
14 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.GroupIdActionBuilder;
\r
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MaxLengthAction;
\r
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MaxLengthActionBuilder;
\r
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MplsTtlAction;
\r
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MplsTtlActionBuilder;
\r
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.NwTtlAction;
\r
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.NwTtlActionBuilder;
\r
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.OxmFieldsAction;
\r
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.OxmFieldsActionBuilder;
\r
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortAction;
\r
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortActionBuilder;
\r
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.QueueIdAction;
\r
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.QueueIdActionBuilder;
\r
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.CopyTtlIn;
\r
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.CopyTtlOut;
\r
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.DecMplsTtl;
\r
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.DecNwTtl;
\r
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.Experimenter;
\r
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.Group;
\r
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.Output;
\r
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PopMpls;
\r
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PopPbb;
\r
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PopVlan;
\r
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PushMpls;
\r
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PushPbb;
\r
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PushVlan;
\r
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetField;
\r
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetMplsTtl;
\r
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetNwTtl;
\r
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetQueue;
\r
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.action.header.ActionBuilder;
\r
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.AnyPortNumber;
\r
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.EtherType;
\r
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber;
\r
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.bucket.ActionsList;
\r
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.bucket.ActionsListBuilder;
\r
52 * Class for easy creation of actions
\r
54 * @author timotej.kubas
\r
55 * @author michal.polkorab
\r
57 public abstract class ActionCreator {
\r
58 final static byte PAD_ACTION_LENGTH = 2;
\r
59 private static ActionBuilder actionBuilder = new ActionBuilder();
\r
60 private static ActionsListBuilder actionsListBuilder = new ActionsListBuilder();
\r
61 private static List<ActionsList> actionsList = new ArrayList<>();
\r
63 * @param inp input ByteBuf
\r
64 * @param bucketsLength length of buckets
\r
65 * @return ActionsList
\r
67 public static List<ActionsList> createActionsList(ByteBuf inp, int bucketsLength) {
\r
68 final byte BUCKET_HEADER_LENGTH = 16;
\r
69 int bucketsCurrentLength = BUCKET_HEADER_LENGTH;
\r
70 int actionsLength = 0;
\r
72 while (bucketsCurrentLength < bucketsLength) {
\r
73 switch(inp.readUnsignedShort()) {
\r
74 case 0: actionsLength = inp.readUnsignedShort(); //outputActionLength
\r
75 actionsList.add(ActionCreator.createOutputAction(inp));
\r
76 bucketsCurrentLength = bucketsCurrentLength + actionsLength;
\r
79 actionsLength = inp.readUnsignedShort();//empty header length
\r
80 actionsList.add(ActionCreator.createCopyTtlOutAction(inp));
\r
81 bucketsCurrentLength = bucketsCurrentLength + actionsLength;
\r
85 actionsLength = inp.readUnsignedShort();//empty header length
\r
86 actionsList.add(ActionCreator.createCopyTtlInAction(inp));
\r
87 bucketsCurrentLength = bucketsCurrentLength + actionsLength;
\r
91 actionsLength = inp.readUnsignedShort();//empty header length
\r
92 actionsList.add(ActionCreator.createSetMplsTtlAction(inp));
\r
93 bucketsCurrentLength = bucketsCurrentLength + actionsLength;
\r
97 actionsLength = inp.readUnsignedShort();//empty header length
\r
98 actionsList.add(ActionCreator.createDecMplsTtlOutAction(inp));
\r
99 bucketsCurrentLength = bucketsCurrentLength + actionsLength;
\r
103 actionsLength = inp.readUnsignedShort();
\r
104 actionsList.add(ActionCreator.createPushVlanAction(inp));
\r
105 bucketsCurrentLength = bucketsCurrentLength + actionsLength;
\r
109 actionsLength = inp.readUnsignedShort();//empty header length
\r
110 actionsList.add(ActionCreator.createPopVlanAction(inp));
\r
111 bucketsCurrentLength = bucketsCurrentLength + actionsLength;
\r
115 actionsLength = inp.readUnsignedShort();//8
\r
116 actionsList.add(ActionCreator.createPushMplsAction(inp));
\r
117 bucketsCurrentLength = bucketsCurrentLength + actionsLength;
\r
121 actionsLength = inp.readUnsignedShort();//8
\r
122 actionsList.add(ActionCreator.createPopMplsAction(inp));
\r
123 bucketsCurrentLength = bucketsCurrentLength + actionsLength;
\r
127 actionsLength = inp.readUnsignedShort();
\r
128 actionsList.add(ActionCreator.createSetQueueAction(inp));
\r
129 bucketsCurrentLength = bucketsCurrentLength + actionsLength;
\r
133 actionsLength = inp.readUnsignedShort();//8
\r
134 actionsList.add(ActionCreator.createGroupAction(inp));
\r
135 bucketsCurrentLength = bucketsCurrentLength + actionsLength;
\r
139 actionsLength = inp.readUnsignedShort();//8
\r
140 actionsList.add(ActionCreator.createSetNwTtlAction(inp));
\r
141 bucketsCurrentLength = bucketsCurrentLength + actionsLength;
\r
145 actionsLength = inp.readUnsignedShort();//empty header length
\r
146 actionsList.add(ActionCreator.createDecNwTtlAction(inp));
\r
147 bucketsCurrentLength = bucketsCurrentLength + actionsLength;
\r
151 actionsLength = inp.readUnsignedShort();//8
\r
153 actionsList.add(ActionCreator.createSetFieldAction(inp, actionsLength));
\r
154 bucketsCurrentLength = bucketsCurrentLength + actionsLength;
\r
157 actionsLength = inp.readUnsignedShort();//8
\r
158 actionsList.add(ActionCreator.createPushPbbAction(inp));
\r
159 bucketsCurrentLength = bucketsCurrentLength + actionsLength;
\r
163 actionsLength = inp.readUnsignedShort();//empty header length
\r
164 actionsList.add(ActionCreator.createPopPbbAction(inp));
\r
165 bucketsCurrentLength = bucketsCurrentLength + actionsLength;
\r
169 actionsLength = inp.readUnsignedShort();
\r
170 actionsList.add(ActionCreator.createExperimenterAction(inp));
\r
171 bucketsCurrentLength = bucketsCurrentLength + actionsLength;
\r
177 return actionsList;
\r
182 * @param action input action that contains empty header
\r
183 * @param in input ByteBuf
\r
186 private static ActionsList createEmptyHeader(Class<? extends org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.Action> action, ByteBuf in) {
\r
187 final byte PADDING_IN_ACTIONS_HEADER = 4;
\r
189 actionBuilder.setType(action);
\r
190 in.skipBytes(PADDING_IN_ACTIONS_HEADER);
\r
191 actionsListBuilder.setAction(actionBuilder.build());
\r
192 return actionsListBuilder.build();
\r
196 * @param in input ByteBuf
\r
199 public static ActionsList createCopyTtlInAction(ByteBuf in) {
\r
200 return createEmptyHeader(CopyTtlIn.class, in);
\r
204 * @param in input ByteBuf
\r
207 public static ActionsList createCopyTtlOutAction(ByteBuf in) {
\r
208 return createEmptyHeader(CopyTtlOut.class, in);
\r
212 * @param in input ByteBuf
\r
215 public static ActionsList createDecMplsTtlOutAction(ByteBuf in) {
\r
216 return createEmptyHeader(DecMplsTtl.class, in);
\r
220 * @param in input ByteBuf
\r
223 public static ActionsList createPopVlanAction(ByteBuf in) {
\r
224 return createEmptyHeader(PopVlan.class, in);
\r
228 * @param in input ByteBuf
\r
231 public static ActionsList createDecNwTtlAction(ByteBuf in) {
\r
232 return createEmptyHeader(DecNwTtl.class, in);
\r
236 * @param in input ByteBuf
\r
239 public static ActionsList createPopPbbAction(ByteBuf in) {
\r
240 return createEmptyHeader(PopPbb.class, in);
\r
244 * @param in input ByteBuf
\r
245 * @return ActionList
\r
247 public static ActionsList createOutputAction(ByteBuf in) {
\r
248 final byte PADDING_IN_OUTPUT_ACTIONS_HEADER = 6;
\r
250 actionBuilder.setType(Output.class);
\r
251 PortActionBuilder port = new PortActionBuilder();
\r
252 port.setPort(new AnyPortNumber(new PortNumber(in.readUnsignedInt())));
\r
253 actionBuilder.addAugmentation(PortAction.class, port.build());
\r
254 MaxLengthActionBuilder maxLen = new MaxLengthActionBuilder();
\r
255 maxLen.setMaxLength(in.readUnsignedShort());
\r
256 actionBuilder.addAugmentation(MaxLengthAction.class, maxLen.build());
\r
257 actionsListBuilder.setAction(actionBuilder.build());
\r
258 in.skipBytes(PADDING_IN_OUTPUT_ACTIONS_HEADER);
\r
260 return actionsListBuilder.build();
\r
264 * @param in input ByteBuf
\r
265 * @return ActionList
\r
267 public static ActionsList createSetMplsTtlAction(ByteBuf in) {
\r
268 final byte PADDING_IN_SET_MPLS_TTL_ACTIONS_HEADER = 3;
\r
270 actionBuilder.setType(SetMplsTtl.class);
\r
271 MplsTtlActionBuilder mplsTtl = new MplsTtlActionBuilder();
\r
272 mplsTtl.setMplsTtl(in.readUnsignedByte());
\r
273 actionBuilder.addAugmentation(MplsTtlAction.class, mplsTtl.build());
\r
274 actionsListBuilder.setAction(actionBuilder.build());
\r
275 in.skipBytes(PADDING_IN_SET_MPLS_TTL_ACTIONS_HEADER);
\r
277 return actionsListBuilder.build();
\r
281 * @param action input action that contains push
\r
282 * @param in input ByteBuf
\r
283 * @return ActionList
\r
285 private static ActionsList createPushAction(Class<? extends org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.Action> action, ByteBuf in) {
\r
286 final byte PADDING_IN_PUSH_VLAN_ACTIONS_HEADER = 2;
\r
288 actionBuilder.setType(action);
\r
289 EthertypeActionBuilder etherType = new EthertypeActionBuilder();
\r
290 etherType.setEthertype(new EtherType(in.readUnsignedShort()));
\r
291 actionBuilder.addAugmentation(EthertypeAction.class, etherType.build());
\r
292 actionsListBuilder.setAction(actionBuilder.build());
\r
293 in.skipBytes(PADDING_IN_PUSH_VLAN_ACTIONS_HEADER);
\r
295 return actionsListBuilder.build();
\r
299 * @param in input ByteBuf
\r
302 public static ActionsList createPushVlanAction(ByteBuf in) {
\r
303 return createPushAction(PushVlan.class, in);
\r
307 * @param in input ByteBuf
\r
310 public static ActionsList createPushMplsAction(ByteBuf in) {
\r
311 return createPushAction(PushMpls.class, in);
\r
315 * @param in input ByteBuf
\r
318 public static ActionsList createPopMplsAction(ByteBuf in) {
\r
319 return createPushAction(PopMpls.class, in);
\r
323 * @param in input ByteBuf
\r
326 public static ActionsList createPushPbbAction(ByteBuf in) {
\r
327 return createPushAction(PushPbb.class, in);
\r
331 * @param in input ByteBuf
\r
332 * @return ActionList
\r
334 public static ActionsList createSetQueueAction(ByteBuf in) {
\r
335 actionBuilder.setType(SetQueue.class);
\r
336 QueueIdActionBuilder queueId = new QueueIdActionBuilder();
\r
337 queueId.setQueueId(in.readUnsignedInt());
\r
338 actionBuilder.addAugmentation(QueueIdAction.class, queueId.build());
\r
339 actionsListBuilder.setAction(actionBuilder.build());
\r
341 return actionsListBuilder.build();
\r
345 * @param in input ByteBuf
\r
346 * @return ActionList
\r
348 public static ActionsList createGroupAction(ByteBuf in) {
\r
349 actionBuilder.setType(Group.class);
\r
350 GroupIdActionBuilder group = new GroupIdActionBuilder();
\r
351 group.setGroupId(in.readUnsignedInt());
\r
352 actionBuilder.addAugmentation(GroupIdAction.class, group.build());
\r
353 actionsListBuilder.setAction(actionBuilder.build());
\r
355 return actionsListBuilder.build();
\r
359 * @param in input ByteBuf
\r
360 * @return ActionList
\r
362 public static ActionsList createExperimenterAction(ByteBuf in) {
\r
363 actionBuilder.setType(Experimenter.class);
\r
364 ExperimenterActionBuilder experimenter = new ExperimenterActionBuilder();
\r
365 experimenter.setExperimenter(in.readUnsignedInt());
\r
366 actionBuilder.addAugmentation(ExperimenterAction.class, experimenter.build());
\r
367 actionsListBuilder.setAction(actionBuilder.build());
\r
369 return actionsListBuilder.build();
\r
373 * @param in input ByteBuf
\r
374 * @return ActionList
\r
376 public static ActionsList createSetNwTtlAction(ByteBuf in) {
\r
377 final byte PADDING_IN_NW_TTL_ACTIONS_HEADER = 3;
\r
379 actionBuilder.setType(SetNwTtl.class);
\r
380 NwTtlActionBuilder nwTtl = new NwTtlActionBuilder();
\r
381 nwTtl.setNwTtl(in.readUnsignedByte());
\r
382 actionBuilder.addAugmentation(NwTtlAction.class, nwTtl.build());
\r
383 actionsListBuilder.setAction(actionBuilder.build());
\r
384 in.skipBytes(PADDING_IN_NW_TTL_ACTIONS_HEADER);
\r
386 return actionsListBuilder.build();
\r
390 * @param in input ByteBuf
\r
391 * @param actionLength length of action
\r
392 * @return ActionList
\r
394 public static ActionsList createSetFieldAction(ByteBuf in, int actionLength) {
\r
395 actionBuilder.setType(SetField.class);
\r
396 OxmFieldsActionBuilder matchEntries = new OxmFieldsActionBuilder();
\r
397 matchEntries.setMatchEntries(MatchEntriesCreator.createMatchEntry(in, actionLength - 4));
\r
398 actionBuilder.addAugmentation(OxmFieldsAction.class, matchEntries.build());
\r
399 actionsListBuilder.setAction(actionBuilder.build());
\r
401 return actionsListBuilder.build();
\r