Extensibility support (deserialization part)
[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.openflowjava.protocol.api.extensibility.DeserializerRegistry;
17 import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistryInjector;
18 import org.opendaylight.openflowjava.protocol.api.extensibility.MessageCodeKey;
19 import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.DlAddressAction;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.DlAddressActionBuilder;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ExperimenterAction;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.IpAddressAction;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.IpAddressActionBuilder;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MaxLengthAction;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MaxLengthActionBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.NwTosAction;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.NwTosActionBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortAction;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortActionBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.QueueIdAction;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.QueueIdActionBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.VlanPcpAction;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.VlanPcpActionBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.VlanVidAction;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.VlanVidActionBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.Enqueue;
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.SetDlDst;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetDlSrc;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetNwDst;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetNwSrc;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetNwTos;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetTpDst;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetTpSrc;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetVlanPcp;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetVlanVid;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.StripVlan;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.grouping.Action;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.grouping.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 class OF10ActionsDeserializer implements OFDeserializer<Action>,
63         DeserializerRegistryInjector {
64     
65     private static final byte PADDING_IN_SET_VLAN_VID_ACTION = 2;
66     private static final byte PADDING_IN_SET_VLAN_PCP_ACTION = 3;
67     private static final byte PADDING_IN_STRIP_VLAN_ACTION = 4;
68     private static final byte PADDING_IN_SET_DL_ACTION = 6;
69     private static final byte PADDING_IN_NW_TOS_ACTION = 3;
70     private static final byte PADDING_IN_TP_ACTION = 2;
71     private static final byte PADDING_IN_ENQUEUE_ACTION = 6;
72     private DeserializerRegistry registry;
73
74     @Override
75     public Action deserialize(ByteBuf input) {
76         int type = input.readUnsignedShort();
77         input.skipBytes(EncodeConstants.SIZE_OF_SHORT_IN_BYTES);
78         ActionBuilder actionsBuilder = new ActionBuilder();
79         Action actionsList = null;
80         switch(type) {
81         case 0:
82             actionsList = createOutputAction(input, actionsBuilder);
83             break;
84         case 1:
85             actionsList = createSetVlanVidAction(input, actionsBuilder);
86             break;
87         case 2:
88             actionsList = createVlanPcpAction(input, actionsBuilder);
89             break;
90         case 3:
91             actionsList = createStripVlanAction(input, actionsBuilder);
92             break;
93         case 4:
94             actionsList = createSetDlSrcAction(input, actionsBuilder);
95             break;
96         case 5:
97             actionsList = createSetDlDstAction(input, actionsBuilder);
98             break;
99         case 6:
100             actionsList = createSetNwSrcAction(input, actionsBuilder);
101             break;
102         case 7:
103             actionsList = createSetNwDstAction(input, actionsBuilder);
104             break;
105         case 8:
106             actionsList = createSetNwTosAction(input, actionsBuilder);
107             break;
108         case 9:
109             actionsList = createSetTpSrcAction(input, actionsBuilder);
110             break;
111         case 10:
112             actionsList = createSetTpDstAction(input, actionsBuilder);
113             break;
114         case 11:
115             actionsList = createEnqueueAction(input, actionsBuilder);
116             break;
117         case 0xFFFF:
118             OFDeserializer<ExperimenterAction> expDeserializer = registry.getDeserializer(
119                     new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, 0xFFFF, ExperimenterAction.class));
120             expDeserializer.deserialize(input);
121             break;
122         default:
123             break;
124         }
125         return actionsList;
126     }
127
128     /**
129      * @param in input ByteBuf
130      * @param builder 
131      * @return ActionList
132      */
133     public static Action createOutputAction(ByteBuf in, ActionBuilder builder) {
134         builder.setType(Output.class);
135         createPortAugmentation(in, builder);
136         MaxLengthActionBuilder maxLen = new MaxLengthActionBuilder();
137         maxLen.setMaxLength(in.readUnsignedShort());
138         builder.addAugmentation(MaxLengthAction.class, maxLen.build());
139         return builder.build();
140     }
141
142     private static Action createSetVlanVidAction(ByteBuf input, ActionBuilder builder) {
143         builder.setType(SetVlanVid.class);
144         VlanVidActionBuilder vlanBuilder = new VlanVidActionBuilder();
145         vlanBuilder.setVlanVid(input.readUnsignedShort());
146         input.skipBytes(PADDING_IN_SET_VLAN_VID_ACTION);
147         builder.addAugmentation(VlanVidAction.class, vlanBuilder.build());
148         return builder.build();
149     }
150
151     private static Action createVlanPcpAction(ByteBuf input, ActionBuilder builder) {
152         builder.setType(SetVlanPcp.class);
153         VlanPcpActionBuilder vlanBuilder = new VlanPcpActionBuilder();
154         vlanBuilder.setVlanPcp(input.readUnsignedByte());
155         input.skipBytes(PADDING_IN_SET_VLAN_PCP_ACTION);
156         builder.addAugmentation(VlanPcpAction.class, vlanBuilder.build());
157         return builder.build();
158     }
159
160     private static Action createStripVlanAction(ByteBuf input, ActionBuilder builder) {
161         builder.setType(StripVlan.class);
162         input.skipBytes(PADDING_IN_STRIP_VLAN_ACTION);
163         return builder.build();
164     }
165
166     private static Action createSetDlSrcAction(ByteBuf input, ActionBuilder builder) {
167         builder.setType(SetDlSrc.class);
168         builder.addAugmentation(DlAddressAction.class, createDlAugmentationAndPad(input));
169         return builder.build();
170     }
171
172     private static Action createSetDlDstAction(ByteBuf input, ActionBuilder builder) {
173         builder.setType(SetDlDst.class);
174         builder.addAugmentation(DlAddressAction.class, createDlAugmentationAndPad(input));
175         return builder.build();
176     }
177     
178     private static DlAddressAction createDlAugmentationAndPad(ByteBuf input) {
179         DlAddressActionBuilder dlBuilder = new DlAddressActionBuilder();
180         byte[] address = new byte[EncodeConstants.MAC_ADDRESS_LENGTH];
181         input.readBytes(address);
182         dlBuilder.setDlAddress(new MacAddress(ByteBufUtils.macAddressToString(address)));
183         input.skipBytes(PADDING_IN_SET_DL_ACTION);
184         return dlBuilder.build();
185     }
186
187     private static Action createSetNwSrcAction(ByteBuf input, ActionBuilder builder) {
188         builder.setType(SetNwSrc.class);
189         builder.addAugmentation(IpAddressAction.class, createNwAddressAugmentationAndPad(input));
190         return builder.build();
191     }
192
193     private static Action createSetNwDstAction(ByteBuf input, ActionBuilder builder) {
194         builder.setType(SetNwDst.class);
195         builder.addAugmentation(IpAddressAction.class, createNwAddressAugmentationAndPad(input));
196         return builder.build();
197     }
198     
199     private static Augmentation<Action> createNwAddressAugmentationAndPad(ByteBuf input) {
200         IpAddressActionBuilder ipBuilder = new IpAddressActionBuilder();
201         List<String> groups = new ArrayList<>();
202         for (int i = 0; i < EncodeConstants.GROUPS_IN_IPV4_ADDRESS; i++) {
203             groups.add(Short.toString(input.readUnsignedByte()));
204         }
205         Joiner joiner = Joiner.on(".");
206         ipBuilder.setIpAddress(new Ipv4Address(joiner.join(groups)));
207         return ipBuilder.build();
208     }
209
210     private static Action createSetNwTosAction(ByteBuf input, ActionBuilder builder) {
211         builder.setType(SetNwTos.class);
212         NwTosActionBuilder tosBuilder = new NwTosActionBuilder();
213         tosBuilder.setNwTos(input.readUnsignedByte());
214         builder.addAugmentation(NwTosAction.class, tosBuilder.build());
215         input.skipBytes(PADDING_IN_NW_TOS_ACTION);
216         return builder.build();
217     }
218
219     private static Action createSetTpSrcAction(ByteBuf input, ActionBuilder builder) {
220         builder.setType(SetTpSrc.class);
221         createPortAugmentation(input, builder);
222         input.skipBytes(PADDING_IN_TP_ACTION);
223         return builder.build();
224     }
225
226     private static Action createSetTpDstAction(ByteBuf input, ActionBuilder builder) {
227         builder.setType(SetTpDst.class);
228         createPortAugmentation(input, builder);
229         input.skipBytes(PADDING_IN_TP_ACTION);
230         return builder.build();
231     }
232     
233     private static void createPortAugmentation(ByteBuf input, ActionBuilder actionBuilder) {
234         PortActionBuilder portBuilder = new PortActionBuilder();
235         portBuilder.setPort(new PortNumber((long) input.readUnsignedShort()));
236         actionBuilder.addAugmentation(PortAction.class, portBuilder.build());
237     }
238
239     private static Action createEnqueueAction(ByteBuf input, ActionBuilder builder) {
240         builder.setType(Enqueue.class);
241         createPortAugmentation(input, builder);
242         input.skipBytes(PADDING_IN_ENQUEUE_ACTION);
243         QueueIdActionBuilder queueBuilder = new QueueIdActionBuilder();
244         queueBuilder.setQueueId(input.readUnsignedInt());
245         builder.addAugmentation(QueueIdAction.class, queueBuilder.build());
246         return builder.build();
247     }
248
249     @Override
250     public void injectDeserializerRegistry(DeserializerRegistry deserializerRegistry) {
251         registry = deserializerRegistry;
252     }
253 }