Minor model refactor
[openflowjava.git] / openflow-protocol-impl / src / main / java / org / opendaylight / openflowjava / protocol / impl / util / ActionsDeserializer.java
1 /*
2  * Copyright (c) 2013 Pantheon Technologies s.r.o. and others. All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.openflowjava.protocol.impl.util;
10
11 import io.netty.buffer.ByteBuf;
12
13 import java.util.ArrayList;
14 import java.util.List;
15
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;
56
57 /**
58  * Deserializes ofp_actions (OpenFlow v1.3)
59  * @author timotej.kubas
60  * @author michal.polkorab
61  */
62 public abstract class ActionsDeserializer {
63     
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     
71     /**
72      * Creates list of actions (OpenFlow v1.3)
73      * @param input input ByteBuf
74      * @param actionsLength length of buckets
75      * @return ActionsList
76      */
77     public static List<Action> createActions(ByteBuf input, int actionsLength) {
78         List<Action> actions = new ArrayList<>();
79         int length = 0;
80         while (length < actionsLength) {
81             int type = input.readUnsignedShort();
82             int currentActionLength = input.readUnsignedShort();
83             ActionBuilder actionBuilder = new ActionBuilder();
84             switch(type) {
85             case 0:
86                 actions.add(createOutputAction(input, actionBuilder));
87                 break;
88             case 11:
89                 actions.add(createCopyTtlOutAction(input, actionBuilder));
90                 break;
91             case 12:
92                 actions.add(createCopyTtlInAction(input, actionBuilder));
93                 break;
94             case 15:
95                 actions.add(createSetMplsTtlAction(input, actionBuilder));
96                 break;
97             case 16:
98                 actions.add(createDecMplsTtlOutAction(input, actionBuilder));
99                 break;
100             case 17:
101                 actions.add(createPushVlanAction(input, actionBuilder));
102                 break;
103             case 18:
104                 actions.add(createPopVlanAction(input, actionBuilder));
105                 break;
106             case 19:
107                 actions.add(createPushMplsAction(input, actionBuilder));
108                 break;
109             case 20:
110                 actions.add(createPopMplsAction(input, actionBuilder));
111                 break;
112             case 21:
113                 actions.add(createSetQueueAction(input, actionBuilder));
114                 break;
115             case 22:
116                 actions.add(createGroupAction(input, actionBuilder));
117                 break;
118             case 23:
119                 actions.add(createSetNwTtlAction(input, actionBuilder));
120                 break;
121             case 24:
122                 actions.add(createDecNwTtlAction(input, actionBuilder));
123                 break;
124             case 25:
125                 actions.add(createSetFieldAction(input, actionBuilder, currentActionLength));
126                 break;
127             case 26:
128                 actions.add(createPushPbbAction(input, actionBuilder));
129                 break;
130             case 27:
131                 actions.add(createPopPbbAction(input, actionBuilder));
132                 break;
133             case 0xFFFF:
134                 actions.add(createExperimenterAction(input, actionBuilder));
135                 break;
136             default:
137                 break;
138             }
139             length += currentActionLength;
140         } 
141         return actions;
142     }
143
144     /**
145      * Creates action ids - actions without values (OpenFlow v1.3)
146      * @param input input ByteBuf
147      * @param actionsLength length of actions
148      * @return ActionsList
149      */
150     public static List<Action> createActionIds(ByteBuf input, int actionsLength) {
151         List<Action> actionsList = new ArrayList<>();
152         int length = 0;
153         ActionBuilder builder;
154         while (length < actionsLength) {
155             builder = new ActionBuilder();
156             int type = input.readUnsignedShort();
157             int currentActionLength = input.readUnsignedShort();
158             switch(type) {
159             case 0:
160                 builder.setType(Output.class);
161                 break;
162             case 11:
163                 builder.setType(CopyTtlOut.class);
164                 break;
165             case 12:
166                 builder.setType(CopyTtlIn.class);
167                 break;
168             case 15:
169                 builder.setType(SetMplsTtl.class);
170                 break;
171             case 16:
172                 builder.setType(DecMplsTtl.class);
173                 break;
174             case 17:
175                 builder.setType(PushVlan.class);
176                 break;
177             case 18:
178                 builder.setType(PopVlan.class);
179                 break;
180             case 19:
181                 builder.setType(PushMpls.class);
182                 break;
183             case 20:
184                 builder.setType(PopMpls.class);
185                 break;
186             case 21:
187                 builder.setType(SetQueue.class);
188                 break;
189             case 22:
190                 builder.setType(Group.class);
191                 break;
192             case 23:
193                 builder.setType(SetNwTtl.class);
194                 break;
195             case 24:
196                 builder.setType(DecNwTtl.class);
197                 break;
198             case 25:
199                 builder.setType(SetField.class);
200                 break; 
201             case 26:
202                 builder.setType(PushPbb.class);
203                 break;
204             case 27:
205                 builder.setType(PopPbb.class);
206                 break;
207             case 0xFFFF:
208                 builder.setType(Experimenter.class);
209                 ExperimenterActionBuilder experimenter = new ExperimenterActionBuilder();
210                 experimenter.setExperimenter(input.readUnsignedInt());
211                 builder.addAugmentation(ExperimenterAction.class, experimenter.build());
212                 break;
213             default: 
214                 break;
215             }
216             actionsList.add(builder.build());
217             length += currentActionLength;
218         } 
219         return actionsList;
220     }
221
222     private static Action createEmptyHeader(Class<? extends ActionBase> action,
223             ByteBuf in, ActionBuilder actionBuilder) {
224         actionBuilder.setType(action);
225         in.skipBytes(PADDING_IN_ACTIONS_HEADER);
226         return actionBuilder.build();
227     }
228     
229     private static Action createCopyTtlInAction(ByteBuf in, ActionBuilder actionBuilder) {
230         return createEmptyHeader(CopyTtlIn.class, in, actionBuilder);
231     }
232
233     private static Action createCopyTtlOutAction(ByteBuf in, ActionBuilder actionBuilder) {
234         return createEmptyHeader(CopyTtlOut.class, in, actionBuilder);
235     }
236     
237     private static Action createDecMplsTtlOutAction(ByteBuf in, ActionBuilder actionBuilder) {
238         return createEmptyHeader(DecMplsTtl.class, in, actionBuilder);
239     }
240     
241     private static Action createPopVlanAction(ByteBuf in, ActionBuilder actionBuilder) {
242         return createEmptyHeader(PopVlan.class, in, actionBuilder);
243     }
244     
245     private static Action createDecNwTtlAction(ByteBuf in, ActionBuilder actionBuilder) {
246         return createEmptyHeader(DecNwTtl.class, in, actionBuilder);
247     }
248     
249     private static Action createPopPbbAction(ByteBuf in, ActionBuilder actionBuilder) {
250         return createEmptyHeader(PopPbb.class, in, actionBuilder);
251     }
252     
253     private static Action createOutputAction(ByteBuf in, ActionBuilder actionBuilder) {
254         actionBuilder.setType(Output.class);
255         PortActionBuilder port = new PortActionBuilder();
256         port.setPort(new PortNumber(in.readUnsignedInt()));
257         actionBuilder.addAugmentation(PortAction.class, port.build());
258         MaxLengthActionBuilder maxLen = new MaxLengthActionBuilder();
259         maxLen.setMaxLength(in.readUnsignedShort());
260         actionBuilder.addAugmentation(MaxLengthAction.class, maxLen.build());
261         in.skipBytes(PADDING_IN_OUTPUT_ACTIONS_HEADER);
262         return actionBuilder.build();
263     }
264     
265     private static Action createSetMplsTtlAction(ByteBuf in, ActionBuilder actionBuilder) {
266         actionBuilder.setType(SetMplsTtl.class);
267         MplsTtlActionBuilder mplsTtl = new MplsTtlActionBuilder();
268         mplsTtl.setMplsTtl(in.readUnsignedByte());
269         actionBuilder.addAugmentation(MplsTtlAction.class, mplsTtl.build());
270         in.skipBytes(PADDING_IN_SET_MPLS_TTL_ACTIONS_HEADER);
271         return actionBuilder.build();
272     }
273     
274     private static Action createPushAction(Class<? extends ActionBase> action,
275             ByteBuf in, ActionBuilder actionBuilder) {
276         actionBuilder.setType(action);
277         EthertypeActionBuilder etherType = new EthertypeActionBuilder();
278         etherType.setEthertype(new EtherType(in.readUnsignedShort()));
279         actionBuilder.addAugmentation(EthertypeAction.class, etherType.build());
280         in.skipBytes(PADDING_IN_PUSH_VLAN_ACTIONS_HEADER);
281         return actionBuilder.build();
282     }
283     
284     private static Action createPushVlanAction(ByteBuf in, ActionBuilder actionBuilder) {
285         return createPushAction(PushVlan.class, in, actionBuilder);
286     }
287     
288     private static Action createPushMplsAction(ByteBuf in, ActionBuilder actionBuilder) {
289         return createPushAction(PushMpls.class, in, actionBuilder);
290     }
291     
292     private static Action createPopMplsAction(ByteBuf in, ActionBuilder actionBuilder) {
293         return createPushAction(PopMpls.class, in, actionBuilder);
294     }
295     
296     private static Action createPushPbbAction(ByteBuf in, ActionBuilder actionBuilder) {
297         return createPushAction(PushPbb.class, in, actionBuilder);
298     }
299     
300     private static Action createSetQueueAction(ByteBuf in, ActionBuilder actionBuilder) {
301         actionBuilder.setType(SetQueue.class);
302         QueueIdActionBuilder queueId = new QueueIdActionBuilder();
303         queueId.setQueueId(in.readUnsignedInt());
304         actionBuilder.addAugmentation(QueueIdAction.class, queueId.build());
305         return actionBuilder.build();
306     }
307     
308     private static Action createGroupAction(ByteBuf in, ActionBuilder actionBuilder) {
309         actionBuilder.setType(Group.class);
310         GroupIdActionBuilder group = new GroupIdActionBuilder();
311         group.setGroupId(in.readUnsignedInt());
312         actionBuilder.addAugmentation(GroupIdAction.class, group.build());
313         return actionBuilder.build();
314     }
315     
316     private static Action createExperimenterAction(ByteBuf in, ActionBuilder actionBuilder) {
317         actionBuilder.setType(Experimenter.class);
318         ExperimenterActionBuilder experimenter = new ExperimenterActionBuilder();
319         experimenter.setExperimenter(in.readUnsignedInt());
320         actionBuilder.addAugmentation(ExperimenterAction.class, experimenter.build());
321         return actionBuilder.build();
322     }
323     
324     private static Action createSetNwTtlAction(ByteBuf in, ActionBuilder actionBuilder) {
325         actionBuilder.setType(SetNwTtl.class);
326         NwTtlActionBuilder nwTtl = new NwTtlActionBuilder();
327         nwTtl.setNwTtl(in.readUnsignedByte());
328         actionBuilder.addAugmentation(NwTtlAction.class, nwTtl.build());
329         in.skipBytes(PADDING_IN_NW_TTL_ACTIONS_HEADER);
330         return actionBuilder.build();
331     }
332     
333     private static Action createSetFieldAction(ByteBuf in, ActionBuilder actionBuilder, int actionLength) {
334         actionBuilder.setType(SetField.class);
335         OxmFieldsActionBuilder matchEntries = new OxmFieldsActionBuilder();
336         matchEntries.setMatchEntries(MatchDeserializer.createMatchEntry(in, actionLength  - ACTION_HEADER_LENGTH));
337         actionBuilder.addAugmentation(OxmFieldsAction.class, matchEntries.build());
338         return actionBuilder.build();
339     }
340 }