3610d73535d588bd6b95b8c0dc95e338d65cea91
[openflowjava.git] / openflow-protocol-impl / src / main / java / org / opendaylight / openflowjava / protocol / impl / util / ActionCreator.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.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
50 \r
51 /**\r
52  * Class for easy creation of actions\r
53  * \r
54  * @author timotej.kubas\r
55  * @author michal.polkorab\r
56  */\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
62 /**\r
63  * @param inp input ByteBuf\r
64  * @param bucketsLength length of buckets\r
65  * @return ActionsList\r
66  */\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
71             \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
77                         break;\r
78                 case 11: \r
79                          actionsLength = inp.readUnsignedShort();//empty header length\r
80                          actionsList.add(ActionCreator.createCopyTtlOutAction(inp));\r
81                          bucketsCurrentLength = bucketsCurrentLength + actionsLength;\r
82                          break;\r
83                          \r
84                 case 12: \r
85                          actionsLength = inp.readUnsignedShort();//empty header length\r
86                          actionsList.add(ActionCreator.createCopyTtlInAction(inp));\r
87                          bucketsCurrentLength = bucketsCurrentLength + actionsLength;\r
88                          break;\r
89                 \r
90                 case 15: \r
91                          actionsLength = inp.readUnsignedShort();//empty header length\r
92                          actionsList.add(ActionCreator.createSetMplsTtlAction(inp));\r
93                          bucketsCurrentLength = bucketsCurrentLength + actionsLength;\r
94                          break;\r
95                          \r
96                 case 16:                              \r
97                          actionsLength = inp.readUnsignedShort();//empty header length\r
98                          actionsList.add(ActionCreator.createDecMplsTtlOutAction(inp));\r
99                          bucketsCurrentLength = bucketsCurrentLength + actionsLength;\r
100                          break;\r
101                          \r
102                 case 17: \r
103                          actionsLength = inp.readUnsignedShort();\r
104                          actionsList.add(ActionCreator.createPushVlanAction(inp));\r
105                          bucketsCurrentLength = bucketsCurrentLength + actionsLength;\r
106                          break;\r
107                          \r
108                 case 18:                              \r
109                          actionsLength = inp.readUnsignedShort();//empty header length\r
110                          actionsList.add(ActionCreator.createPopVlanAction(inp));\r
111                          bucketsCurrentLength = bucketsCurrentLength + actionsLength;\r
112                          break;\r
113                          \r
114                 case 19: \r
115                          actionsLength = inp.readUnsignedShort();//8\r
116                          actionsList.add(ActionCreator.createPushMplsAction(inp));\r
117                          bucketsCurrentLength = bucketsCurrentLength + actionsLength;\r
118                          break;\r
119                          \r
120                 case 20: \r
121                          actionsLength = inp.readUnsignedShort();//8\r
122                          actionsList.add(ActionCreator.createPopMplsAction(inp));\r
123                          bucketsCurrentLength = bucketsCurrentLength + actionsLength;\r
124                          break;\r
125                          \r
126                 case 21: \r
127                          actionsLength = inp.readUnsignedShort();\r
128                          actionsList.add(ActionCreator.createSetQueueAction(inp));\r
129                          bucketsCurrentLength = bucketsCurrentLength + actionsLength;\r
130                          break;\r
131                          \r
132                 case 22: \r
133                         actionsLength = inp.readUnsignedShort();//8\r
134                         actionsList.add(ActionCreator.createGroupAction(inp));\r
135                         bucketsCurrentLength = bucketsCurrentLength + actionsLength;\r
136                         break;\r
137                         \r
138                 case 23: \r
139                          actionsLength = inp.readUnsignedShort();//8\r
140                          actionsList.add(ActionCreator.createSetNwTtlAction(inp));\r
141                          bucketsCurrentLength = bucketsCurrentLength + actionsLength;\r
142                          break;\r
143                         \r
144                 case 24:                              \r
145                         actionsLength = inp.readUnsignedShort();//empty header length\r
146                         actionsList.add(ActionCreator.createDecNwTtlAction(inp));\r
147                         bucketsCurrentLength = bucketsCurrentLength + actionsLength;\r
148                         break;\r
149                         \r
150                 case 25:\r
151                         actionsLength = inp.readUnsignedShort();//8\r
152                         //TODO field\r
153                         actionsList.add(ActionCreator.createSetFieldAction(inp, actionsLength));\r
154                         bucketsCurrentLength = bucketsCurrentLength + actionsLength;\r
155                         break; \r
156                 case 26: \r
157                          actionsLength = inp.readUnsignedShort();//8\r
158                          actionsList.add(ActionCreator.createPushPbbAction(inp));\r
159                          bucketsCurrentLength = bucketsCurrentLength + actionsLength;\r
160                          break;\r
161                          \r
162                 case 27:                              \r
163                         actionsLength = inp.readUnsignedShort();//empty header length\r
164                         actionsList.add(ActionCreator.createPopPbbAction(inp));\r
165                         bucketsCurrentLength = bucketsCurrentLength + actionsLength;\r
166                         break;\r
167                         \r
168                 case 0xFFFF: \r
169                         actionsLength = inp.readUnsignedShort();\r
170                         actionsList.add(ActionCreator.createExperimenterAction(inp));\r
171                         bucketsCurrentLength = bucketsCurrentLength + actionsLength;\r
172                         break;\r
173                 default: \r
174                          break;\r
175                 }\r
176             } \r
177         return actionsList;\r
178     }\r
179     \r
180     \r
181     /**\r
182      * @param action input action that contains empty header\r
183      * @param in input ByteBuf \r
184      * @return Action\r
185      */\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
188         \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
193     }\r
194     \r
195     /**\r
196      * @param in input ByteBuf\r
197      * @return Action\r
198      */\r
199     public static ActionsList createCopyTtlInAction(ByteBuf in) {\r
200         return createEmptyHeader(CopyTtlIn.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 createCopyTtlOutAction(ByteBuf in) {\r
208         return createEmptyHeader(CopyTtlOut.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 createDecMplsTtlOutAction(ByteBuf in) {\r
216         return createEmptyHeader(DecMplsTtl.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 createPopVlanAction(ByteBuf in) {\r
224         return createEmptyHeader(PopVlan.class, in);\r
225     }\r
226     \r
227     /**\r
228      * @param in input ByteBuf\r
229      * @return Action\r
230      */\r
231     public static ActionsList createDecNwTtlAction(ByteBuf in) {\r
232         return createEmptyHeader(DecNwTtl.class, in);\r
233     }\r
234     \r
235     /**\r
236      * @param in input ByteBuf\r
237      * @return Action\r
238      */\r
239     public static ActionsList createPopPbbAction(ByteBuf in) {\r
240         return createEmptyHeader(PopPbb.class, in);\r
241     }\r
242     \r
243     /**\r
244      * @param in input ByteBuf\r
245      * @return ActionList\r
246      */\r
247     public static ActionsList createOutputAction(ByteBuf in) {\r
248         final byte PADDING_IN_OUTPUT_ACTIONS_HEADER = 6;\r
249         \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
259         \r
260         return actionsListBuilder.build();\r
261     }\r
262     \r
263     /**\r
264      * @param in input ByteBuf\r
265      * @return ActionList\r
266      */\r
267     public static ActionsList createSetMplsTtlAction(ByteBuf in) {\r
268         final byte PADDING_IN_SET_MPLS_TTL_ACTIONS_HEADER = 3;\r
269         \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
276         \r
277         return actionsListBuilder.build();\r
278     }\r
279     \r
280     /**\r
281      * @param action input action that contains push\r
282      * @param in input ByteBuf\r
283      * @return ActionList\r
284      */\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
287         \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
294         \r
295         return actionsListBuilder.build();\r
296     }\r
297     \r
298     /**\r
299      * @param in input ByteBuf\r
300      * @return Action\r
301      */\r
302     public static ActionsList createPushVlanAction(ByteBuf in) {\r
303         return createPushAction(PushVlan.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 createPushMplsAction(ByteBuf in) {\r
311         return createPushAction(PushMpls.class, in);\r
312     }\r
313     \r
314     /**\r
315      * @param in input ByteBuf\r
316      * @return Action\r
317      */\r
318     public static ActionsList createPopMplsAction(ByteBuf in) {\r
319         return createPushAction(PopMpls.class, in);\r
320     }\r
321     \r
322     /**\r
323      * @param in input ByteBuf\r
324      * @return Action\r
325      */\r
326     public static ActionsList createPushPbbAction(ByteBuf in) {\r
327         return createPushAction(PushPbb.class, in);\r
328     }\r
329     \r
330     /**\r
331      * @param in input ByteBuf\r
332      * @return ActionList\r
333      */\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
340         \r
341         return actionsListBuilder.build();\r
342     }\r
343     \r
344     /**\r
345      * @param in input ByteBuf\r
346      * @return ActionList\r
347      */\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
354         \r
355         return actionsListBuilder.build();\r
356     }\r
357     \r
358     /**\r
359      * @param in input ByteBuf\r
360      * @return ActionList\r
361      */\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
368         \r
369         return actionsListBuilder.build();\r
370     }\r
371     \r
372     /**\r
373      * @param in input ByteBuf\r
374      * @return ActionList\r
375      */\r
376     public static ActionsList createSetNwTtlAction(ByteBuf in) {\r
377         final byte PADDING_IN_NW_TTL_ACTIONS_HEADER = 3;\r
378         \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
385         \r
386         return actionsListBuilder.build();\r
387     }\r
388     \r
389     /**\r
390      * @param in input ByteBuf\r
391      * @param actionLength length of action\r
392      * @return ActionList\r
393      */\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
400         \r
401         return actionsListBuilder.build();\r
402     }\r
403 }\r