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