Merge "OF1.3 matchSerializer (Ipv6 address) fix + test"
[openflowjava.git] / openflow-protocol-impl / src / main / java / org / opendaylight / openflowjava / protocol / impl / util / OF10ActionsDeserializer.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.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;\r
10 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;\r
11 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.DlAddressAction;\r
12 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.DlAddressActionBuilder;\r
13 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ExperimenterActionBuilder;\r
14 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.IpAddressAction;\r
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.IpAddressActionBuilder;\r
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MaxLengthAction;\r
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MaxLengthActionBuilder;\r
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.NwTosAction;\r
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.NwTosActionBuilder;\r
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortAction;\r
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortActionBuilder;\r
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.QueueIdAction;\r
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.QueueIdActionBuilder;\r
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.VlanPcpActionBuilder;\r
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.VlanVidAction;\r
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.VlanVidActionBuilder;\r
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.Enqueue;\r
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.Output;\r
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetDlDst;\r
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetDlSrc;\r
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetNwDst;\r
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetNwSrc;\r
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetNwTos;\r
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetTpDst;\r
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetTpSrc;\r
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetVlanPcp;\r
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetVlanVid;\r
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.StripVlan;\r
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.ActionsList;\r
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.ActionsListBuilder;\r
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.actions.list.Action;\r
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.actions.list.ActionBuilder;\r
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber;\r
44 import org.opendaylight.yangtools.yang.binding.Augmentation;\r
45 \r
46 import com.google.common.base.Joiner;\r
47 \r
48 /**\r
49  * Deserializes ofp_action (OpenFlow v1.0) structures\r
50  * @author michal.polkorab\r
51  */\r
52 public class OF10ActionsDeserializer {\r
53     \r
54     private static final byte PADDING_IN_SET_VLAN_VID_ACTION = 2;\r
55     private static final byte PADDING_IN_SET_VLAN_PCP_ACTION = 3;\r
56     private static final byte PADDING_IN_STRIP_VLAN_ACTION = 4;\r
57     private static final byte PADDING_IN_SET_DL_ACTION = 6;\r
58     private static final byte PADDING_IN_NW_TOS_ACTION = 3;\r
59     private static final byte PADDING_IN_TP_ACTION = 2;\r
60     private static final byte PADDING_IN_ENQUEUE_ACTION = 6;\r
61 \r
62     /**\r
63      * Creates list of actions (OpenFlow v1.0) from ofp_action structures\r
64      * @param input input ByteBuf\r
65      * @return ActionsList list of actions\r
66      */\r
67     public static List<ActionsList> createActionsList(ByteBuf input) {\r
68         List<ActionsList> actions = new ArrayList<>();\r
69         while (input.readableBytes() > 0) {\r
70             ActionsListBuilder actionsBuilder = new ActionsListBuilder();\r
71             int type = input.readUnsignedShort();\r
72             input.skipBytes(EncodeConstants.SIZE_OF_SHORT_IN_BYTES);\r
73             switch(type) {\r
74             case 0:  \r
75                 actions.add(createOutputAction(input, actionsBuilder));\r
76                 break;\r
77             case 1: \r
78                 actions.add(createSetVlanVidAction(input, actionsBuilder));\r
79                 break;\r
80             case 2: \r
81                 actions.add(createVlanPcpAction(input, actionsBuilder));\r
82                 break;\r
83             case 3: \r
84                 actions.add(createStripVlanAction(input, actionsBuilder));\r
85                 break;\r
86             case 4:                              \r
87                 actions.add(createSetDlSrcAction(input, actionsBuilder));\r
88                 break;\r
89             case 5: \r
90                 actions.add(createSetDlDstAction(input, actionsBuilder));\r
91                 break;\r
92             case 6:                              \r
93                 actions.add(createSetNwSrcAction(input, actionsBuilder));\r
94                 break;\r
95             case 7: \r
96                 actions.add(createSetNwDstAction(input, actionsBuilder));\r
97                 break;\r
98             case 8: \r
99                 actions.add(createSetNwTosAction(input, actionsBuilder));\r
100                 break;\r
101             case 9: \r
102                 actions.add(createSetTpSrcAction(input, actionsBuilder));\r
103                 break;\r
104             case 10: \r
105                 actions.add(createSetTpDstAction(input, actionsBuilder));\r
106                 break;\r
107             case 11: \r
108                 actions.add(createEnqueueAction(input, actionsBuilder));\r
109                 break;\r
110             case 0xFFFF:\r
111                 actions.add(createExperimenterAction(input, actionsBuilder));\r
112                 break;\r
113             default: \r
114                 break;\r
115             }\r
116         } \r
117         return actions;\r
118     }\r
119 \r
120     /**\r
121      * @param in input ByteBuf\r
122      * @param builder \r
123      * @return ActionList\r
124      */\r
125     public static ActionsList createOutputAction(ByteBuf in, ActionsListBuilder builder) {\r
126         ActionBuilder actionBuilder = new ActionBuilder();\r
127         actionBuilder.setType(Output.class);\r
128         createPortAugmentation(in, actionBuilder);\r
129         MaxLengthActionBuilder maxLen = new MaxLengthActionBuilder();\r
130         maxLen.setMaxLength(in.readUnsignedShort());\r
131         actionBuilder.addAugmentation(MaxLengthAction.class, maxLen.build());\r
132         builder.setAction(actionBuilder.build());\r
133         return builder.build();\r
134     }\r
135 \r
136     private static ActionsList createSetVlanVidAction(ByteBuf input, ActionsListBuilder builder) {\r
137         ActionBuilder actionBuilder = new ActionBuilder();\r
138         actionBuilder.setType(SetVlanVid.class);\r
139         VlanVidActionBuilder vlanBuilder = new VlanVidActionBuilder();\r
140         vlanBuilder.setVlanVid(input.readUnsignedShort());\r
141         input.skipBytes(PADDING_IN_SET_VLAN_VID_ACTION);\r
142         actionBuilder.addAugmentation(VlanVidAction.class, vlanBuilder.build());\r
143         builder.setAction(actionBuilder.build());\r
144         return builder.build();\r
145     }\r
146 \r
147     private static ActionsList createVlanPcpAction(ByteBuf input, ActionsListBuilder builder) {\r
148         ActionBuilder actionBuilder = new ActionBuilder();\r
149         actionBuilder.setType(SetVlanPcp.class);\r
150         VlanPcpActionBuilder vlanBuilder = new VlanPcpActionBuilder();\r
151         vlanBuilder.setVlanPcp(input.readUnsignedByte());\r
152         input.skipBytes(PADDING_IN_SET_VLAN_PCP_ACTION);\r
153         actionBuilder.addAugmentation(VlanVidAction.class, vlanBuilder.build());\r
154         builder.setAction(actionBuilder.build());\r
155         return builder.build();\r
156     }\r
157 \r
158     private static ActionsList createStripVlanAction(ByteBuf input, ActionsListBuilder builder) {\r
159         ActionBuilder actionBuilder = new ActionBuilder();\r
160         actionBuilder.setType(StripVlan.class);\r
161         input.skipBytes(PADDING_IN_STRIP_VLAN_ACTION);\r
162         builder.setAction(actionBuilder.build());\r
163         return builder.build();\r
164     }\r
165 \r
166     private static ActionsList createSetDlSrcAction(ByteBuf input, ActionsListBuilder builder) {\r
167         ActionBuilder actionBuilder = new ActionBuilder();\r
168         actionBuilder.setType(SetDlSrc.class);\r
169         actionBuilder.addAugmentation(DlAddressAction.class, createDlAugmentationAndPad(input));\r
170         builder.setAction(actionBuilder.build());\r
171         return builder.build();\r
172     }\r
173 \r
174     private static ActionsList createSetDlDstAction(ByteBuf input, ActionsListBuilder builder) {\r
175         ActionBuilder actionBuilder = new ActionBuilder();\r
176         actionBuilder.setType(SetDlDst.class);\r
177         actionBuilder.addAugmentation(DlAddressAction.class, createDlAugmentationAndPad(input));\r
178         builder.setAction(actionBuilder.build());\r
179         return builder.build();\r
180     }\r
181     \r
182     private static DlAddressAction createDlAugmentationAndPad(ByteBuf input) {\r
183         DlAddressActionBuilder dlBuilder = new DlAddressActionBuilder();\r
184         byte[] address = new byte[EncodeConstants.MAC_ADDRESS_LENGTH];\r
185         input.readBytes(address);\r
186         dlBuilder.setDlAddress(new MacAddress(ByteBufUtils.macAddressToString(address)));\r
187         input.skipBytes(PADDING_IN_SET_DL_ACTION);\r
188         return dlBuilder.build();\r
189     }\r
190 \r
191     private static ActionsList createSetNwSrcAction(ByteBuf input, ActionsListBuilder builder) {\r
192         ActionBuilder actionBuilder = new ActionBuilder();\r
193         actionBuilder.setType(SetNwSrc.class);\r
194         actionBuilder.addAugmentation(IpAddressAction.class, createNwAddressAugmentationAndPad(input));\r
195         builder.setAction(actionBuilder.build());\r
196         return builder.build();\r
197     }\r
198 \r
199     private static ActionsList createSetNwDstAction(ByteBuf input, ActionsListBuilder builder) {\r
200         ActionBuilder actionBuilder = new ActionBuilder();\r
201         actionBuilder.setType(SetNwDst.class);\r
202         actionBuilder.addAugmentation(IpAddressAction.class, createNwAddressAugmentationAndPad(input));\r
203         builder.setAction(actionBuilder.build());\r
204         return builder.build();\r
205     }\r
206     \r
207     private static Augmentation<Action> createNwAddressAugmentationAndPad(ByteBuf input) {\r
208         IpAddressActionBuilder ipBuilder = new IpAddressActionBuilder();\r
209         List<String> groups = new ArrayList<>();\r
210         for (int i = 0; i < EncodeConstants.GROUPS_IN_IPV4_ADDRESS; i++) {\r
211             groups.add(Short.toString(input.readUnsignedByte()));\r
212         }\r
213         Joiner joiner = Joiner.on(".");\r
214         ipBuilder.setIpAddress(new Ipv4Address(joiner.join(groups)));\r
215         return ipBuilder.build();\r
216     }\r
217 \r
218     private static ActionsList createSetNwTosAction(ByteBuf input, ActionsListBuilder builder) {\r
219         ActionBuilder actionBuilder = new ActionBuilder();\r
220         actionBuilder.setType(SetNwTos.class);\r
221         NwTosActionBuilder tosBuilder = new NwTosActionBuilder();\r
222         tosBuilder.setNwTos(input.readUnsignedByte());\r
223         actionBuilder.addAugmentation(NwTosAction.class, tosBuilder.build());\r
224         input.skipBytes(PADDING_IN_NW_TOS_ACTION);\r
225         builder.setAction(actionBuilder.build());\r
226         return builder.build();\r
227     }\r
228 \r
229     private static ActionsList createSetTpSrcAction(ByteBuf input, ActionsListBuilder builder) {\r
230         ActionBuilder actionBuilder = new ActionBuilder();\r
231         actionBuilder.setType(SetTpSrc.class);\r
232         createPortAugmentation(input, actionBuilder);\r
233         input.skipBytes(PADDING_IN_TP_ACTION);\r
234         builder.setAction(actionBuilder.build());\r
235         return builder.build();\r
236     }\r
237 \r
238     private static ActionsList createSetTpDstAction(ByteBuf input, ActionsListBuilder builder) {\r
239         ActionBuilder actionBuilder = new ActionBuilder();\r
240         actionBuilder.setType(SetTpDst.class);\r
241         createPortAugmentation(input, actionBuilder);\r
242         input.skipBytes(PADDING_IN_TP_ACTION);\r
243         builder.setAction(actionBuilder.build());\r
244         return builder.build();\r
245     }\r
246     \r
247     private static void createPortAugmentation(ByteBuf input, ActionBuilder actionBuilder) {\r
248         PortActionBuilder portBuilder = new PortActionBuilder();\r
249         portBuilder.setPort(new PortNumber((long) input.readUnsignedShort()));\r
250         actionBuilder.addAugmentation(PortAction.class, portBuilder.build());\r
251     }\r
252 \r
253     private static ActionsList createEnqueueAction(ByteBuf input, ActionsListBuilder builder) {\r
254         ActionBuilder actionBuilder = new ActionBuilder();\r
255         actionBuilder.setType(Enqueue.class);\r
256         createPortAugmentation(input, actionBuilder);\r
257         input.skipBytes(PADDING_IN_ENQUEUE_ACTION);\r
258         QueueIdActionBuilder queueBuilder = new QueueIdActionBuilder();\r
259         queueBuilder.setQueueId(input.readUnsignedInt());\r
260         actionBuilder.addAugmentation(QueueIdAction.class, queueBuilder.build());\r
261         builder.setAction(actionBuilder.build());\r
262         return builder.build();\r
263     }\r
264 \r
265     private static ActionsList createExperimenterAction(ByteBuf input, ActionsListBuilder builder) {\r
266         ActionBuilder actionBuilder = new ActionBuilder();\r
267         actionBuilder.setType(Enqueue.class);\r
268         ExperimenterActionBuilder expBuilder = new ExperimenterActionBuilder();\r
269         expBuilder.setExperimenter(input.readUnsignedInt());\r
270         actionBuilder.addAugmentation(QueueIdAction.class, expBuilder.build());\r
271         builder.setAction(actionBuilder.build());\r
272         return builder.build();\r
273     }\r
274     \r
275     \r
276 }\r