589d86bf48f5d9a521c6e67a0f392547f45a2a5e
[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.action.header.ActionBuilder;\r
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.ActionsList;\r
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.ActionsListBuilder;\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     final static byte PAD_ACTION_LENGTH = 2;\r
58     private static ActionBuilder actionBuilder = new ActionBuilder();\r
59     private static ActionsListBuilder actionsListBuilder = new ActionsListBuilder();\r
60     private static List<ActionsList> actionsList = new ArrayList<>();\r
61     \r
62     /**\r
63      * @param input input ByteBuf\r
64      * @param bucketsLength length of buckets\r
65      * @return ActionsList\r
66      */\r
67     public static List<ActionsList> createActionsList(ByteBuf input, int bucketsLength) {\r
68         final byte BUCKET_HEADER_LENGTH = 16;\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                         //TODO field\r
140                         actionsList.add(ActionsDeserializer.createSetFieldAction(input, actionsLength));\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.urn.opendaylight.openflow.common.types.rev130731.Action> action, ByteBuf in) {\r
171         final byte PADDING_IN_ACTIONS_HEADER = 4;\r
172         \r
173         actionBuilder.setType(action);\r
174         in.skipBytes(PADDING_IN_ACTIONS_HEADER);\r
175         actionsListBuilder.setAction(actionBuilder.build());\r
176         return actionsListBuilder.build();\r
177     }\r
178     \r
179     /**\r
180      * @param in input ByteBuf\r
181      * @return Action\r
182      */\r
183     public static ActionsList createCopyTtlInAction(ByteBuf in) {\r
184         return createEmptyHeader(CopyTtlIn.class, in);\r
185     }\r
186     \r
187     /**\r
188      * @param in input ByteBuf\r
189      * @return Action\r
190      */\r
191     public static ActionsList createCopyTtlOutAction(ByteBuf in) {\r
192         return createEmptyHeader(CopyTtlOut.class, in);\r
193     }\r
194     \r
195     /**\r
196      * @param in input ByteBuf\r
197      * @return Action\r
198      */\r
199     public static ActionsList createDecMplsTtlOutAction(ByteBuf in) {\r
200         return createEmptyHeader(DecMplsTtl.class, in);\r
201     }\r
202     \r
203     /**\r
204      * @param in input ByteBuf\r
205      * @return Action\r
206      */\r
207     public static ActionsList createPopVlanAction(ByteBuf in) {\r
208         return createEmptyHeader(PopVlan.class, in);\r
209     }\r
210     \r
211     /**\r
212      * @param in input ByteBuf\r
213      * @return Action\r
214      */\r
215     public static ActionsList createDecNwTtlAction(ByteBuf in) {\r
216         return createEmptyHeader(DecNwTtl.class, in);\r
217     }\r
218     \r
219     /**\r
220      * @param in input ByteBuf\r
221      * @return Action\r
222      */\r
223     public static ActionsList createPopPbbAction(ByteBuf in) {\r
224         return createEmptyHeader(PopPbb.class, in);\r
225     }\r
226     \r
227     /**\r
228      * @param in input ByteBuf\r
229      * @return ActionList\r
230      */\r
231     public static ActionsList createOutputAction(ByteBuf in) {\r
232         final byte PADDING_IN_OUTPUT_ACTIONS_HEADER = 6;\r
233         \r
234         actionBuilder.setType(Output.class);\r
235         PortActionBuilder port = new PortActionBuilder();\r
236         port.setPort(new PortNumber(in.readUnsignedInt()));\r
237         actionBuilder.addAugmentation(PortAction.class, port.build());\r
238         MaxLengthActionBuilder maxLen = new MaxLengthActionBuilder();\r
239         maxLen.setMaxLength(in.readUnsignedShort());\r
240         actionBuilder.addAugmentation(MaxLengthAction.class, maxLen.build());\r
241         actionsListBuilder.setAction(actionBuilder.build());\r
242         in.skipBytes(PADDING_IN_OUTPUT_ACTIONS_HEADER);\r
243         \r
244         return actionsListBuilder.build();\r
245     }\r
246     \r
247     /**\r
248      * @param in input ByteBuf\r
249      * @return ActionList\r
250      */\r
251     public static ActionsList createSetMplsTtlAction(ByteBuf in) {\r
252         final byte PADDING_IN_SET_MPLS_TTL_ACTIONS_HEADER = 3;\r
253         \r
254         actionBuilder.setType(SetMplsTtl.class);\r
255         MplsTtlActionBuilder mplsTtl = new MplsTtlActionBuilder();\r
256         mplsTtl.setMplsTtl(in.readUnsignedByte());\r
257         actionBuilder.addAugmentation(MplsTtlAction.class, mplsTtl.build());\r
258         actionsListBuilder.setAction(actionBuilder.build());\r
259         in.skipBytes(PADDING_IN_SET_MPLS_TTL_ACTIONS_HEADER);\r
260         \r
261         return actionsListBuilder.build();\r
262     }\r
263     \r
264     /**\r
265      * @param action input action that contains push\r
266      * @param in input ByteBuf\r
267      * @return ActionList\r
268      */\r
269     private static ActionsList createPushAction(Class<? extends org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.Action> action, ByteBuf in) {\r
270         final byte PADDING_IN_PUSH_VLAN_ACTIONS_HEADER = 2;\r
271         \r
272         actionBuilder.setType(action);\r
273         EthertypeActionBuilder etherType = new EthertypeActionBuilder();\r
274         etherType.setEthertype(new EtherType(in.readUnsignedShort()));\r
275         actionBuilder.addAugmentation(EthertypeAction.class, etherType.build());\r
276         actionsListBuilder.setAction(actionBuilder.build());\r
277         in.skipBytes(PADDING_IN_PUSH_VLAN_ACTIONS_HEADER);\r
278         \r
279         return actionsListBuilder.build();\r
280     }\r
281     \r
282     /**\r
283      * @param in input ByteBuf\r
284      * @return Action\r
285      */\r
286     public static ActionsList createPushVlanAction(ByteBuf in) {\r
287         return createPushAction(PushVlan.class, in);\r
288     }\r
289     \r
290     /**\r
291      * @param in input ByteBuf\r
292      * @return Action\r
293      */\r
294     public static ActionsList createPushMplsAction(ByteBuf in) {\r
295         return createPushAction(PushMpls.class, in);\r
296     }\r
297     \r
298     /**\r
299      * @param in input ByteBuf\r
300      * @return Action\r
301      */\r
302     public static ActionsList createPopMplsAction(ByteBuf in) {\r
303         return createPushAction(PopMpls.class, in);\r
304     }\r
305     \r
306     /**\r
307      * @param in input ByteBuf\r
308      * @return Action\r
309      */\r
310     public static ActionsList createPushPbbAction(ByteBuf in) {\r
311         return createPushAction(PushPbb.class, in);\r
312     }\r
313     \r
314     /**\r
315      * @param in input ByteBuf\r
316      * @return ActionList\r
317      */\r
318     public static ActionsList createSetQueueAction(ByteBuf in) {\r
319         actionBuilder.setType(SetQueue.class);\r
320         QueueIdActionBuilder queueId = new QueueIdActionBuilder();\r
321         queueId.setQueueId(in.readUnsignedInt());\r
322         actionBuilder.addAugmentation(QueueIdAction.class, queueId.build());\r
323         actionsListBuilder.setAction(actionBuilder.build());\r
324         \r
325         return actionsListBuilder.build();\r
326     }\r
327     \r
328     /**\r
329      * @param in input ByteBuf\r
330      * @return ActionList\r
331      */\r
332     public static ActionsList createGroupAction(ByteBuf in) {\r
333         actionBuilder.setType(Group.class);\r
334         GroupIdActionBuilder group = new GroupIdActionBuilder();\r
335         group.setGroupId(in.readUnsignedInt());\r
336         actionBuilder.addAugmentation(GroupIdAction.class, group.build());\r
337         actionsListBuilder.setAction(actionBuilder.build());\r
338         \r
339         return actionsListBuilder.build();\r
340     }\r
341     \r
342     /**\r
343      * @param in input ByteBuf\r
344      * @return ActionList\r
345      */\r
346     public static ActionsList createExperimenterAction(ByteBuf in) {\r
347         actionBuilder.setType(Experimenter.class);\r
348         ExperimenterActionBuilder experimenter = new ExperimenterActionBuilder();\r
349         experimenter.setExperimenter(in.readUnsignedInt());\r
350         actionBuilder.addAugmentation(ExperimenterAction.class, experimenter.build());\r
351         actionsListBuilder.setAction(actionBuilder.build());\r
352         \r
353         return actionsListBuilder.build();\r
354     }\r
355     \r
356     /**\r
357      * @param in input ByteBuf\r
358      * @return ActionList\r
359      */\r
360     public static ActionsList createSetNwTtlAction(ByteBuf in) {\r
361         final byte PADDING_IN_NW_TTL_ACTIONS_HEADER = 3;\r
362         \r
363         actionBuilder.setType(SetNwTtl.class);\r
364         NwTtlActionBuilder nwTtl = new NwTtlActionBuilder();\r
365         nwTtl.setNwTtl(in.readUnsignedByte());\r
366         actionBuilder.addAugmentation(NwTtlAction.class, nwTtl.build());\r
367         actionsListBuilder.setAction(actionBuilder.build());\r
368         in.skipBytes(PADDING_IN_NW_TTL_ACTIONS_HEADER);\r
369         \r
370         return actionsListBuilder.build();\r
371     }\r
372     \r
373     /**\r
374      * @param in input ByteBuf\r
375      * @param actionLength length of action\r
376      * @return ActionList\r
377      */\r
378     public static ActionsList createSetFieldAction(ByteBuf in, int actionLength) {\r
379         actionBuilder.setType(SetField.class);\r
380         OxmFieldsActionBuilder matchEntries = new OxmFieldsActionBuilder();\r
381         matchEntries.setMatchEntries(MatchEntriesDeserializer.createMatchEntries(in, actionLength - 4));\r
382         actionBuilder.addAugmentation(OxmFieldsAction.class, matchEntries.build());\r
383         actionsListBuilder.setAction(actionBuilder.build());\r
384         \r
385         return actionsListBuilder.build();\r
386     }\r
387 }\r