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