2 * Copyright (c) 2013 Pantheon Technologies s.r.o. and others. All rights reserved.
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
9 package org.opendaylight.openflowjava.protocol.impl.util;
11 import io.netty.buffer.ByteBuf;
13 import java.util.ArrayList;
14 import java.util.List;
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;
56 import com.google.common.base.Joiner;
59 * Deserializes ofp_action (OpenFlow v1.0) structures
60 * @author michal.polkorab
62 public abstract class OF10ActionsDeserializer {
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;
73 * Creates list of actions (OpenFlow v1.0) from ofp_action structures
74 * @param input input ByteBuf
75 * @return ActionsList list of actions
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));
88 * Creates list of actions (OpenFlow v1.0) from ofp_action structures, which are not the last structure
90 * @param input input ByteBuf
91 * @param actionsLength length of actions
92 * @return ActionsList list of actions
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));
105 private static ActionsList decodeAction(ByteBuf input, int type) {
106 ActionsListBuilder actionsBuilder = new ActionsListBuilder();
107 ActionsList actionsList = null;
110 actionsList = createOutputAction(input, actionsBuilder);
113 actionsList = createSetVlanVidAction(input, actionsBuilder);
116 actionsList = createVlanPcpAction(input, actionsBuilder);
119 actionsList = createStripVlanAction(input, actionsBuilder);
122 actionsList = createSetDlSrcAction(input, actionsBuilder);
125 actionsList = createSetDlDstAction(input, actionsBuilder);
128 actionsList = createSetNwSrcAction(input, actionsBuilder);
131 actionsList = createSetNwDstAction(input, actionsBuilder);
134 actionsList = createSetNwTosAction(input, actionsBuilder);
137 actionsList = createSetTpSrcAction(input, actionsBuilder);
140 actionsList = createSetTpDstAction(input, actionsBuilder);
143 actionsList = createEnqueueAction(input, actionsBuilder);
146 actionsList = createExperimenterAction(input, actionsBuilder);
155 * @param in input ByteBuf
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();
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();
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();
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();
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();
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();
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();
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();
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();
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()));
247 Joiner joiner = Joiner.on(".");
248 ipBuilder.setIpAddress(new Ipv4Address(joiner.join(groups)));
249 return ipBuilder.build();
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();
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();
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();
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());
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();
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();