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