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