Merge "OF1.3 matchSerializer (Ipv6 address) fix + test"
[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  * Deserializes ofp_actions (OpenFlow v1.3)\r
52  * @author timotej.kubas\r
53  * @author michal.polkorab\r
54  */\r
55 public abstract class ActionsDeserializer {\r
56     \r
57     private static final byte ACTION_HEADER_LENGTH = 4;\r
58     private static final byte PADDING_IN_ACTIONS_HEADER = 4;\r
59     private static final byte PADDING_IN_OUTPUT_ACTIONS_HEADER = 6;\r
60     private static final byte PADDING_IN_SET_MPLS_TTL_ACTIONS_HEADER = 3;\r
61     private static final byte PADDING_IN_PUSH_VLAN_ACTIONS_HEADER = 2;\r
62     private static final byte PADDING_IN_NW_TTL_ACTIONS_HEADER = 3;\r
63     \r
64     /**\r
65      * Creates list of actions (OpenFlow v1.3)\r
66      * @param input input ByteBuf\r
67      * @param actionsLength length of buckets\r
68      * @return ActionsList\r
69      */\r
70     public static List<ActionsList> createActionsList(ByteBuf input, int actionsLength) {\r
71         ActionsListBuilder actionsListBuilder = new ActionsListBuilder();\r
72         List<ActionsList> actionsList = new ArrayList<>();\r
73         int length = 0;\r
74         while (length < actionsLength) {\r
75             int currentActionLength = 0;\r
76             switch(input.readUnsignedShort()) {\r
77             case 0: currentActionLength = input.readUnsignedShort(); //outputActionLength\r
78             actionsList.add(createOutputAction(input, actionsListBuilder));\r
79             break;\r
80             case 11: \r
81                 currentActionLength = input.readUnsignedShort();//empty header length\r
82                 actionsList.add(createCopyTtlOutAction(input, actionsListBuilder));\r
83                 break;\r
84 \r
85             case 12: \r
86                 currentActionLength = input.readUnsignedShort();//empty header length\r
87                 actionsList.add(createCopyTtlInAction(input, actionsListBuilder));\r
88                 break;\r
89 \r
90             case 15: \r
91                 currentActionLength = input.readUnsignedShort();//empty header length\r
92                 actionsList.add(createSetMplsTtlAction(input, actionsListBuilder));\r
93                 break;\r
94 \r
95             case 16:                              \r
96                 currentActionLength = input.readUnsignedShort();//empty header length\r
97                 actionsList.add(createDecMplsTtlOutAction(input, actionsListBuilder));\r
98                 break;\r
99 \r
100             case 17: \r
101                 currentActionLength = input.readUnsignedShort();\r
102                 actionsList.add(createPushVlanAction(input, actionsListBuilder));\r
103                 break;\r
104 \r
105             case 18:                              \r
106                 currentActionLength = input.readUnsignedShort();//empty header length\r
107                 actionsList.add(createPopVlanAction(input, actionsListBuilder));\r
108                 break;\r
109 \r
110             case 19: \r
111                 currentActionLength = input.readUnsignedShort();//8\r
112                 actionsList.add(createPushMplsAction(input, actionsListBuilder));\r
113                 break;\r
114 \r
115             case 20: \r
116                 currentActionLength = input.readUnsignedShort();//8\r
117                 actionsList.add(createPopMplsAction(input, actionsListBuilder));\r
118                 break;\r
119 \r
120             case 21: \r
121                 currentActionLength = input.readUnsignedShort();\r
122                 actionsList.add(createSetQueueAction(input, actionsListBuilder));\r
123                 break;\r
124 \r
125             case 22: \r
126                 currentActionLength = input.readUnsignedShort();//8\r
127                 actionsList.add(createGroupAction(input, actionsListBuilder));\r
128                 break;\r
129 \r
130             case 23: \r
131                 currentActionLength = input.readUnsignedShort();//8\r
132                 actionsList.add(createSetNwTtlAction(input, actionsListBuilder));\r
133                 break;\r
134 \r
135             case 24:                              \r
136                 currentActionLength = input.readUnsignedShort();//empty header length\r
137                 actionsList.add(createDecNwTtlAction(input, actionsListBuilder));\r
138                 break;\r
139 \r
140             case 25:\r
141                 currentActionLength = input.readUnsignedShort();//8\r
142                 actionsList.add(createSetFieldAction(input, actionsListBuilder, currentActionLength));\r
143                 break; \r
144             case 26: \r
145                 currentActionLength = input.readUnsignedShort();//8\r
146                 actionsList.add(createPushPbbAction(input, actionsListBuilder));\r
147                 break;\r
148 \r
149             case 27:                              \r
150                 currentActionLength = input.readUnsignedShort();//empty header length\r
151                 actionsList.add(createPopPbbAction(input, actionsListBuilder));\r
152                 break;\r
153 \r
154             case 0xFFFF: \r
155                 currentActionLength = input.readUnsignedShort();\r
156                 actionsList.add(createExperimenterAction(input, actionsListBuilder));\r
157                 break;\r
158             default: \r
159                 break;\r
160             }\r
161             length += currentActionLength;\r
162         } \r
163         return actionsList;\r
164     }\r
165     \r
166     private static ActionsList createEmptyHeader(Class<? extends org.opendaylight.yang.gen.v1.\r
167             urn.opendaylight.openflow.common.types.rev130731.Action> action,\r
168             ByteBuf in, ActionsListBuilder actionsListBuilder) {\r
169         ActionBuilder actionBuilder = new ActionBuilder();\r
170         actionBuilder.setType(action);\r
171         in.skipBytes(PADDING_IN_ACTIONS_HEADER);\r
172         actionsListBuilder.setAction(actionBuilder.build());\r
173         return actionsListBuilder.build();\r
174     }\r
175     \r
176     private static ActionsList createCopyTtlInAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {\r
177         return createEmptyHeader(CopyTtlIn.class, in, actionsListBuilder);\r
178     }\r
179 \r
180     private static ActionsList createCopyTtlOutAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {\r
181         return createEmptyHeader(CopyTtlOut.class, in, actionsListBuilder);\r
182     }\r
183     \r
184     private static ActionsList createDecMplsTtlOutAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {\r
185         return createEmptyHeader(DecMplsTtl.class, in, actionsListBuilder);\r
186     }\r
187     \r
188     private static ActionsList createPopVlanAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {\r
189         return createEmptyHeader(PopVlan.class, in, actionsListBuilder);\r
190     }\r
191     \r
192     private static ActionsList createDecNwTtlAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {\r
193         return createEmptyHeader(DecNwTtl.class, in, actionsListBuilder);\r
194     }\r
195     \r
196     private static ActionsList createPopPbbAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {\r
197         return createEmptyHeader(PopPbb.class, in, actionsListBuilder);\r
198     }\r
199     \r
200     private static ActionsList createOutputAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {\r
201         ActionBuilder actionBuilder = new ActionBuilder();\r
202         actionBuilder.setType(Output.class);\r
203         PortActionBuilder port = new PortActionBuilder();\r
204         port.setPort(new PortNumber(in.readUnsignedInt()));\r
205         actionBuilder.addAugmentation(PortAction.class, port.build());\r
206         MaxLengthActionBuilder maxLen = new MaxLengthActionBuilder();\r
207         maxLen.setMaxLength(in.readUnsignedShort());\r
208         actionBuilder.addAugmentation(MaxLengthAction.class, maxLen.build());\r
209         actionsListBuilder.setAction(actionBuilder.build());\r
210         in.skipBytes(PADDING_IN_OUTPUT_ACTIONS_HEADER);\r
211         return actionsListBuilder.build();\r
212     }\r
213     \r
214     private static ActionsList createSetMplsTtlAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {\r
215         ActionBuilder actionBuilder = new ActionBuilder();\r
216         actionBuilder.setType(SetMplsTtl.class);\r
217         MplsTtlActionBuilder mplsTtl = new MplsTtlActionBuilder();\r
218         mplsTtl.setMplsTtl(in.readUnsignedByte());\r
219         actionBuilder.addAugmentation(MplsTtlAction.class, mplsTtl.build());\r
220         actionsListBuilder.setAction(actionBuilder.build());\r
221         in.skipBytes(PADDING_IN_SET_MPLS_TTL_ACTIONS_HEADER);\r
222         return actionsListBuilder.build();\r
223     }\r
224     \r
225     private static ActionsList createPushAction(Class<? extends org.opendaylight.yang.gen.\r
226             v1.urn.opendaylight.openflow.common.types.rev130731.Action> action,\r
227             ByteBuf in, ActionsListBuilder actionsListBuilder) {\r
228         ActionBuilder actionBuilder = new ActionBuilder();\r
229         actionBuilder.setType(action);\r
230         EthertypeActionBuilder etherType = new EthertypeActionBuilder();\r
231         etherType.setEthertype(new EtherType(in.readUnsignedShort()));\r
232         actionBuilder.addAugmentation(EthertypeAction.class, etherType.build());\r
233         actionsListBuilder.setAction(actionBuilder.build());\r
234         in.skipBytes(PADDING_IN_PUSH_VLAN_ACTIONS_HEADER);\r
235         return actionsListBuilder.build();\r
236     }\r
237     \r
238     private static ActionsList createPushVlanAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {\r
239         return createPushAction(PushVlan.class, in, actionsListBuilder);\r
240     }\r
241     \r
242     private static ActionsList createPushMplsAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {\r
243         return createPushAction(PushMpls.class, in, actionsListBuilder);\r
244     }\r
245     \r
246     private static ActionsList createPopMplsAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {\r
247         return createPushAction(PopMpls.class, in, actionsListBuilder);\r
248     }\r
249     \r
250     private static ActionsList createPushPbbAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {\r
251         return createPushAction(PushPbb.class, in, actionsListBuilder);\r
252     }\r
253     \r
254     private static ActionsList createSetQueueAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {\r
255         ActionBuilder actionBuilder = new ActionBuilder();\r
256         actionBuilder.setType(SetQueue.class);\r
257         QueueIdActionBuilder queueId = new QueueIdActionBuilder();\r
258         queueId.setQueueId(in.readUnsignedInt());\r
259         actionBuilder.addAugmentation(QueueIdAction.class, queueId.build());\r
260         actionsListBuilder.setAction(actionBuilder.build());\r
261         return actionsListBuilder.build();\r
262     }\r
263     \r
264     private static ActionsList createGroupAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {\r
265         ActionBuilder actionBuilder = new ActionBuilder();\r
266         actionBuilder.setType(Group.class);\r
267         GroupIdActionBuilder group = new GroupIdActionBuilder();\r
268         group.setGroupId(in.readUnsignedInt());\r
269         actionBuilder.addAugmentation(GroupIdAction.class, group.build());\r
270         actionsListBuilder.setAction(actionBuilder.build());\r
271         return actionsListBuilder.build();\r
272     }\r
273     \r
274     private static ActionsList createExperimenterAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {\r
275         ActionBuilder actionBuilder = new ActionBuilder();\r
276         actionBuilder.setType(Experimenter.class);\r
277         ExperimenterActionBuilder experimenter = new ExperimenterActionBuilder();\r
278         experimenter.setExperimenter(in.readUnsignedInt());\r
279         actionBuilder.addAugmentation(ExperimenterAction.class, experimenter.build());\r
280         actionsListBuilder.setAction(actionBuilder.build());\r
281         return actionsListBuilder.build();\r
282     }\r
283     \r
284     private static ActionsList createSetNwTtlAction(ByteBuf in, ActionsListBuilder actionsListBuilder) {\r
285         ActionBuilder actionBuilder = new ActionBuilder();\r
286         actionBuilder.setType(SetNwTtl.class);\r
287         NwTtlActionBuilder nwTtl = new NwTtlActionBuilder();\r
288         nwTtl.setNwTtl(in.readUnsignedByte());\r
289         actionBuilder.addAugmentation(NwTtlAction.class, nwTtl.build());\r
290         actionsListBuilder.setAction(actionBuilder.build());\r
291         in.skipBytes(PADDING_IN_NW_TTL_ACTIONS_HEADER);\r
292         return actionsListBuilder.build();\r
293     }\r
294     \r
295     private static ActionsList createSetFieldAction(ByteBuf in, ActionsListBuilder actionsListBuilder, int actionLength) {\r
296         ActionBuilder actionBuilder = new ActionBuilder();\r
297         actionBuilder.setType(SetField.class);\r
298         OxmFieldsActionBuilder matchEntries = new OxmFieldsActionBuilder();\r
299         matchEntries.setMatchEntries(MatchDeserializer.createMatchEntry(in, actionLength  - ACTION_HEADER_LENGTH));\r
300         actionBuilder.addAugmentation(OxmFieldsAction.class, matchEntries.build());\r
301         actionsListBuilder.setAction(actionBuilder.build());\r
302         return actionsListBuilder.build();\r
303     }\r
304 }\r