5a55c1b171798c2d25bbe30ed2acc3d829f3cf9c
[openflowjava.git] / openflow-protocol-impl / src / main / java / org / opendaylight / openflowjava / protocol / impl / util / ActionsDeserializer.java
1 /* Copyright (C)2013 Pantheon Technologies, s.r.o. All rights reserved. */\r
2 package org.opendaylight.openflowjava.protocol.impl.util;\r
3 \r
4 import io.netty.buffer.ByteBuf;\r
5 \r
6 import java.util.ArrayList;\r
7 import java.util.List;\r
8 \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.actions.ActionsList;\r
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.ActionsListBuilder;\r
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.actions.list.ActionBuilder;\r
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.EtherType;\r
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber;\r
49 \r
50 /**\r
51  * Class for easy deserialization of actions\r
52  * \r
53  * @author timotej.kubas\r
54  * @author michal.polkorab\r
55  */\r
56 public abstract class ActionsDeserializer {\r
57     \r
58     private static final byte ACTION_HEADER_LENGTH = 4;\r
59     \r
60     /**\r
61      * @param input input ByteBuf\r
62      * @param actionsLength length of buckets\r
63      * @return ActionsList\r
64      */\r
65     public static List<ActionsList> createActionsList(ByteBuf input, int actionsLength) {\r
66         ActionsListBuilder actionsListBuilder = new ActionsListBuilder();\r
67         List<ActionsList> actionsList = new ArrayList<>();\r
68         int length = 0;\r
69         while (length < actionsLength) {\r
70             int currentActionLength = 0;\r
71             switch(input.readUnsignedShort()) {\r
72             case 0: currentActionLength = input.readUnsignedShort(); //outputActionLength\r
73             actionsList.add(ActionsDeserializer.createOutputAction(input, actionsListBuilder));\r
74             break;\r
75             case 11: \r
76                 currentActionLength = input.readUnsignedShort();//empty header length\r
77                 actionsList.add(ActionsDeserializer.createCopyTtlOutAction(input, actionsListBuilder));\r
78                 break;\r
79 \r
80             case 12: \r
81                 currentActionLength = input.readUnsignedShort();//empty header length\r
82                 actionsList.add(ActionsDeserializer.createCopyTtlInAction(input, actionsListBuilder));\r
83                 break;\r
84 \r
85             case 15: \r
86                 currentActionLength = input.readUnsignedShort();//empty header length\r
87                 actionsList.add(ActionsDeserializer.createSetMplsTtlAction(input, actionsListBuilder));\r
88                 break;\r
89 \r
90             case 16:                              \r
91                 currentActionLength = input.readUnsignedShort();//empty header length\r
92                 actionsList.add(ActionsDeserializer.createDecMplsTtlOutAction(input, actionsListBuilder));\r
93                 break;\r
94 \r
95             case 17: \r
96                 currentActionLength = input.readUnsignedShort();\r
97                 actionsList.add(ActionsDeserializer.createPushVlanAction(input, actionsListBuilder));\r
98                 break;\r
99 \r
100             case 18:                              \r
101                 currentActionLength = input.readUnsignedShort();//empty header length\r
102                 actionsList.add(ActionsDeserializer.createPopVlanAction(input, actionsListBuilder));\r
103                 break;\r
104 \r
105             case 19: \r
106                 currentActionLength = input.readUnsignedShort();//8\r
107                 actionsList.add(ActionsDeserializer.createPushMplsAction(input, actionsListBuilder));\r
108                 break;\r
109 \r
110             case 20: \r
111                 currentActionLength = input.readUnsignedShort();//8\r
112                 actionsList.add(ActionsDeserializer.createPopMplsAction(input, actionsListBuilder));\r
113                 break;\r
114 \r
115             case 21: \r
116                 currentActionLength = input.readUnsignedShort();\r
117                 actionsList.add(ActionsDeserializer.createSetQueueAction(input, actionsListBuilder));\r
118                 break;\r
119 \r
120             case 22: \r
121                 currentActionLength = input.readUnsignedShort();//8\r
122                 actionsList.add(ActionsDeserializer.createGroupAction(input, actionsListBuilder));\r
123                 break;\r
124 \r
125             case 23: \r
126                 currentActionLength = input.readUnsignedShort();//8\r
127                 actionsList.add(ActionsDeserializer.createSetNwTtlAction(input, actionsListBuilder));\r
128                 break;\r
129 \r
130             case 24:                              \r
131                 currentActionLength = input.readUnsignedShort();//empty header length\r
132                 actionsList.add(ActionsDeserializer.createDecNwTtlAction(input, actionsListBuilder));\r
133                 break;\r
134 \r
135             case 25:\r
136                 currentActionLength = input.readUnsignedShort();//8\r
137                 actionsList.add(ActionsDeserializer.createSetFieldAction(input, actionsListBuilder,\r
138                         currentActionLength));\r
139                 break; \r
140             case 26: \r
141                 currentActionLength = input.readUnsignedShort();//8\r
142                 actionsList.add(ActionsDeserializer.createPushPbbAction(input, actionsListBuilder));\r
143                 break;\r
144 \r
145             case 27:                              \r
146                 currentActionLength = input.readUnsignedShort();//empty header length\r
147                 actionsList.add(ActionsDeserializer.createPopPbbAction(input, actionsListBuilder));\r
148                 break;\r
149 \r
150             case 0xFFFF: \r
151                 currentActionLength = input.readUnsignedShort();\r
152                 actionsList.add(ActionsDeserializer.createExperimenterAction(input, actionsListBuilder));\r
153                 break;\r
154             default: \r
155                 break;\r
156             }\r
157             length += currentActionLength;\r
158         } \r
159         return actionsList;\r
160     }\r
161     \r
162     \r
163     /**\r
164      * @param action input action that contains empty header\r
165      * @param in input ByteBuf \r
166      * @param actionsListBuilder \r
167      * @return Action\r
168      */\r
169     private static ActionsList createEmptyHeader(Class<? extends org.opendaylight.yang.gen.v1.\r
170             urn.opendaylight.openflow.common.types.rev130731.Action> action,\r
171             ByteBuf in, ActionsListBuilder actionsListBuilder) {\r
172         final byte PADDING_IN_ACTIONS_HEADER = 4;\r
173         ActionBuilder actionBuilder = new ActionBuilder();\r
174         actionBuilder.setType(action);\r
175         in.skipBytes(PADDING_IN_ACTIONS_HEADER);\r
176         actionsListBuilder.setAction(actionBuilder.build());\r
177         return actionsListBuilder.build();\r
178     }\r
179     \r
180     /**\r
181      * @param in input ByteBuf\r
182      * @param actionsListBuilder \r
183      * @return Action\r
184      */\r
185     public static ActionsList createCopyTtlInAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {\r
186         return createEmptyHeader(CopyTtlIn.class, in, actionsListBuilder);\r
187     }\r
188     \r
189     /**\r
190      * @param in input ByteBuf\r
191      * @param actionsListBuilder \r
192      * @return Action\r
193      */\r
194     public static ActionsList createCopyTtlOutAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {\r
195         return createEmptyHeader(CopyTtlOut.class, in, actionsListBuilder);\r
196     }\r
197     \r
198     /**\r
199      * @param in input ByteBuf\r
200      * @param actionsListBuilder \r
201      * @return Action\r
202      */\r
203     public static ActionsList createDecMplsTtlOutAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {\r
204         return createEmptyHeader(DecMplsTtl.class, in, actionsListBuilder);\r
205     }\r
206     \r
207     /**\r
208      * @param in input ByteBuf\r
209      * @param actionsListBuilder \r
210      * @return Action\r
211      */\r
212     public static ActionsList createPopVlanAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {\r
213         return createEmptyHeader(PopVlan.class, in, actionsListBuilder);\r
214     }\r
215     \r
216     /**\r
217      * @param in input ByteBuf\r
218      * @param actionsListBuilder \r
219      * @return Action\r
220      */\r
221     public static ActionsList createDecNwTtlAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {\r
222         return createEmptyHeader(DecNwTtl.class, in, actionsListBuilder);\r
223     }\r
224     \r
225     /**\r
226      * @param in input ByteBuf\r
227      * @param actionsListBuilder \r
228      * @return Action\r
229      */\r
230     public static ActionsList createPopPbbAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {\r
231         return createEmptyHeader(PopPbb.class, in, actionsListBuilder);\r
232     }\r
233     \r
234     /**\r
235      * @param in input ByteBuf\r
236      * @param actionsListBuilder \r
237      * @return ActionList\r
238      */\r
239     public static ActionsList createOutputAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {\r
240         final byte PADDING_IN_OUTPUT_ACTIONS_HEADER = 6;\r
241         ActionBuilder actionBuilder = new ActionBuilder();\r
242         actionBuilder.setType(Output.class);\r
243         PortActionBuilder port = new PortActionBuilder();\r
244         port.setPort(new PortNumber(in.readUnsignedInt()));\r
245         actionBuilder.addAugmentation(PortAction.class, port.build());\r
246         MaxLengthActionBuilder maxLen = new MaxLengthActionBuilder();\r
247         maxLen.setMaxLength(in.readUnsignedShort());\r
248         actionBuilder.addAugmentation(MaxLengthAction.class, maxLen.build());\r
249         actionsListBuilder.setAction(actionBuilder.build());\r
250         in.skipBytes(PADDING_IN_OUTPUT_ACTIONS_HEADER);\r
251         \r
252         return actionsListBuilder.build();\r
253     }\r
254     \r
255     /**\r
256      * @param in input ByteBuf\r
257      * @param actionsListBuilder \r
258      * @return ActionList\r
259      */\r
260     public static ActionsList createSetMplsTtlAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {\r
261         final byte PADDING_IN_SET_MPLS_TTL_ACTIONS_HEADER = 3;\r
262         ActionBuilder actionBuilder = new ActionBuilder();\r
263         actionBuilder.setType(SetMplsTtl.class);\r
264         MplsTtlActionBuilder mplsTtl = new MplsTtlActionBuilder();\r
265         mplsTtl.setMplsTtl(in.readUnsignedByte());\r
266         actionBuilder.addAugmentation(MplsTtlAction.class, mplsTtl.build());\r
267         actionsListBuilder.setAction(actionBuilder.build());\r
268         in.skipBytes(PADDING_IN_SET_MPLS_TTL_ACTIONS_HEADER);\r
269         \r
270         return actionsListBuilder.build();\r
271     }\r
272     \r
273     /**\r
274      * @param action input action that contains push\r
275      * @param in input ByteBuf\r
276      * @param actionsListBuilder \r
277      * @return ActionList\r
278      */\r
279     private static ActionsList createPushAction(Class<? extends org.opendaylight.yang.gen.\r
280             v1.urn.opendaylight.openflow.common.types.rev130731.Action> action,\r
281             ByteBuf in, ActionsListBuilder actionsListBuilder) {\r
282         final byte PADDING_IN_PUSH_VLAN_ACTIONS_HEADER = 2;\r
283         ActionBuilder actionBuilder = new ActionBuilder();\r
284         actionBuilder.setType(action);\r
285         EthertypeActionBuilder etherType = new EthertypeActionBuilder();\r
286         etherType.setEthertype(new EtherType(in.readUnsignedShort()));\r
287         actionBuilder.addAugmentation(EthertypeAction.class, etherType.build());\r
288         actionsListBuilder.setAction(actionBuilder.build());\r
289         in.skipBytes(PADDING_IN_PUSH_VLAN_ACTIONS_HEADER);\r
290         \r
291         return actionsListBuilder.build();\r
292     }\r
293     \r
294     /**\r
295      * @param in input ByteBuf\r
296      * @param actionsListBuilder \r
297      * @return Action\r
298      */\r
299     public static ActionsList createPushVlanAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {\r
300         return createPushAction(PushVlan.class, in, actionsListBuilder);\r
301     }\r
302     \r
303     /**\r
304      * @param in input ByteBuf\r
305      * @param actionsListBuilder \r
306      * @return Action\r
307      */\r
308     public static ActionsList createPushMplsAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {\r
309         return createPushAction(PushMpls.class, in, actionsListBuilder);\r
310     }\r
311     \r
312     /**\r
313      * @param in input ByteBuf\r
314      * @param actionsListBuilder \r
315      * @return Action\r
316      */\r
317     public static ActionsList createPopMplsAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {\r
318         return createPushAction(PopMpls.class, in, actionsListBuilder);\r
319     }\r
320     \r
321     /**\r
322      * @param in input ByteBuf\r
323      * @param actionsListBuilder \r
324      * @return Action\r
325      */\r
326     public static ActionsList createPushPbbAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {\r
327         return createPushAction(PushPbb.class, in, actionsListBuilder);\r
328     }\r
329     \r
330     /**\r
331      * @param in input ByteBuf\r
332      * @param actionsListBuilder \r
333      * @return ActionList\r
334      */\r
335     public static ActionsList createSetQueueAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {\r
336         ActionBuilder actionBuilder = new ActionBuilder();\r
337         actionBuilder.setType(SetQueue.class);\r
338         QueueIdActionBuilder queueId = new QueueIdActionBuilder();\r
339         queueId.setQueueId(in.readUnsignedInt());\r
340         actionBuilder.addAugmentation(QueueIdAction.class, queueId.build());\r
341         actionsListBuilder.setAction(actionBuilder.build());\r
342         \r
343         return actionsListBuilder.build();\r
344     }\r
345     \r
346     /**\r
347      * @param in input ByteBuf\r
348      * @param actionsListBuilder \r
349      * @return ActionList\r
350      */\r
351     public static ActionsList createGroupAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {\r
352         ActionBuilder actionBuilder = new ActionBuilder();\r
353         actionBuilder.setType(Group.class);\r
354         GroupIdActionBuilder group = new GroupIdActionBuilder();\r
355         group.setGroupId(in.readUnsignedInt());\r
356         actionBuilder.addAugmentation(GroupIdAction.class, group.build());\r
357         actionsListBuilder.setAction(actionBuilder.build());\r
358         \r
359         return actionsListBuilder.build();\r
360     }\r
361     \r
362     /**\r
363      * @param in input ByteBuf\r
364      * @param actionsListBuilder \r
365      * @return ActionList\r
366      */\r
367     public static ActionsList createExperimenterAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {\r
368         ActionBuilder actionBuilder = new ActionBuilder();\r
369         actionBuilder.setType(Experimenter.class);\r
370         ExperimenterActionBuilder experimenter = new ExperimenterActionBuilder();\r
371         experimenter.setExperimenter(in.readUnsignedInt());\r
372         actionBuilder.addAugmentation(ExperimenterAction.class, experimenter.build());\r
373         actionsListBuilder.setAction(actionBuilder.build());\r
374         \r
375         return actionsListBuilder.build();\r
376     }\r
377     \r
378     /**\r
379      * @param in input ByteBuf\r
380      * @param actionsListBuilder \r
381      * @return ActionList\r
382      */\r
383     public static ActionsList createSetNwTtlAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {\r
384         final byte PADDING_IN_NW_TTL_ACTIONS_HEADER = 3;\r
385         ActionBuilder actionBuilder = new ActionBuilder();\r
386         actionBuilder.setType(SetNwTtl.class);\r
387         NwTtlActionBuilder nwTtl = new NwTtlActionBuilder();\r
388         nwTtl.setNwTtl(in.readUnsignedByte());\r
389         actionBuilder.addAugmentation(NwTtlAction.class, nwTtl.build());\r
390         actionsListBuilder.setAction(actionBuilder.build());\r
391         in.skipBytes(PADDING_IN_NW_TTL_ACTIONS_HEADER);\r
392         \r
393         return actionsListBuilder.build();\r
394     }\r
395     \r
396     /**\r
397      * @param in input ByteBuf\r
398      * @param actionsListBuilder \r
399      * @param actionLength length of action\r
400      * @return ActionList\r
401      */\r
402     public static ActionsList createSetFieldAction(ByteBuf in, ActionsListBuilder actionsListBuilder, int actionLength) {\r
403         ActionBuilder actionBuilder = new ActionBuilder();\r
404         actionBuilder.setType(SetField.class);\r
405         OxmFieldsActionBuilder matchEntries = new OxmFieldsActionBuilder();\r
406         matchEntries.setMatchEntries(MatchDeserializer.createMatchEntry(in, actionLength  - ACTION_HEADER_LENGTH));\r
407         actionBuilder.addAugmentation(OxmFieldsAction.class, matchEntries.build());\r
408         actionsListBuilder.setAction(actionBuilder.build());\r
409         \r
410         return actionsListBuilder.build();\r
411     }\r
412 }\r