Added support for OF 1.0
[openflowjava.git] / openflow-protocol-impl / src / main / java / org / opendaylight / openflowjava / protocol / impl / util / OF10ActionsSerializer.java
1 /* Copyright (C)2013 Pantheon Technologies, s.r.o. All rights reserved. */\r
2 package org.opendaylight.openflowjava.protocol.impl.util;\r
3 \r
4 import io.netty.buffer.ByteBuf;\r
5 \r
6 import java.util.List;\r
7 \r
8 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.DlAddressAction;\r
9 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ExperimenterAction;\r
10 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.IpAddressAction;\r
11 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MaxLengthAction;\r
12 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.NwTosAction;\r
13 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortAction;\r
14 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.QueueIdAction;\r
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.VlanPcpAction;\r
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.VlanVidAction;\r
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.Enqueue;\r
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.Experimenter;\r
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.Output;\r
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetDlDst;\r
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetDlSrc;\r
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetNwDst;\r
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetNwSrc;\r
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetNwTos;\r
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetTpDst;\r
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetTpSrc;\r
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetVlanPcp;\r
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetVlanVid;\r
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.StripVlan;\r
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.ActionsList;\r
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.actions.list.Action;\r
32 \r
33 /**\r
34  * @author michal.polkorab\r
35  *\r
36  */\r
37 public abstract class OF10ActionsSerializer {\r
38     \r
39     /**\r
40      * Encodes actions (OpenFlow v1.0)\r
41      * @param out\r
42      * @param actionsList\r
43      */\r
44     public static void encodeActionsV10(ByteBuf out, List<ActionsList> actionsList) {\r
45         if (actionsList == null) {\r
46             return;\r
47         }\r
48         for (ActionsList list : actionsList) {\r
49             Action action = list.getAction();\r
50             if (action.getType().equals(Output.class)) {\r
51                 encodeOutputAction(action, out);\r
52             } else if (action.getType().equals(SetVlanVid.class)) {\r
53                 encodeSetVlanVidAction(action, out);\r
54             } else if (action.getType().equals(SetVlanPcp.class)) {\r
55                 encodeSetVlanPcpAction(action, out);\r
56             } else if (action.getType().equals(StripVlan.class)) {\r
57                 final byte STRIP_VLAN_CODE = 3;\r
58                 encodeGenericAction(STRIP_VLAN_CODE, out);\r
59             } else if (action.getType().equals(SetDlSrc.class)) {\r
60                 final byte SET_DL_SRC_CODE = 4;\r
61                 encodeDlAddressAction(action, out, SET_DL_SRC_CODE);\r
62             } else if (action.getType().equals(SetDlDst.class)) {\r
63                 final byte SET_DL_DST_CODE = 5;\r
64                 encodeDlAddressAction(action, out, SET_DL_DST_CODE);\r
65             } else if (action.getType().equals(SetNwSrc.class)) {\r
66                 final byte SET_NW_SRC_CODE = 6;\r
67                 encodeIpAddressAction(action, out, SET_NW_SRC_CODE);\r
68             } else if (action.getType().equals(SetNwDst.class)) {\r
69                 final byte SET_NW_DST_CODE = 7;\r
70                 encodeIpAddressAction(action, out, SET_NW_DST_CODE);\r
71             } else if (action.getType().equals(SetNwTos.class)) {\r
72                 encodeNwTosAction(action, out);\r
73             } else if (action.getType().equals(SetTpSrc.class)) {\r
74                 final byte SET_TP_SRC_CODE = 9;\r
75                 encodeTpPortAction(action, out, SET_TP_SRC_CODE);\r
76             } else if (action.getType().equals(SetTpDst.class)) {\r
77                 final byte SET_TP_DST_CODE = 10;\r
78                 encodeTpPortAction(action, out, SET_TP_DST_CODE);\r
79             } else if (action.getType().equals(Enqueue.class)) {\r
80                 encodeEnqueueAction(action, out);\r
81             } else if (action.getType().equals(Experimenter.class)) {\r
82                 encodeExperimenterAction(action, out);\r
83             }\r
84         }\r
85     }\r
86     \r
87     private static void encodeGenericAction(byte code, ByteBuf out) {\r
88         final byte GENERIC_ACTION_LENGTH = 8;\r
89         final byte PADDING_IN_GENERIC_ACTION = 4;\r
90         out.writeShort(code);\r
91         out.writeShort(GENERIC_ACTION_LENGTH);\r
92         ByteBufUtils.padBuffer(PADDING_IN_GENERIC_ACTION, out);\r
93     }\r
94     \r
95     private static void encodeOutputAction(Action action, ByteBuf out) {\r
96         final byte OUTPUT_CODE = 0;\r
97         final byte OUTPUT_LENGTH = 8;\r
98         out.writeShort(OUTPUT_CODE);\r
99         out.writeShort(OUTPUT_LENGTH);\r
100         PortAction port = action.getAugmentation(PortAction.class);\r
101         out.writeShort(port.getPort().getValue().intValue());\r
102         MaxLengthAction maxlength = action.getAugmentation(MaxLengthAction.class);\r
103         out.writeShort(maxlength.getMaxLength());\r
104     }\r
105     \r
106     private static void encodeSetVlanVidAction(Action action, ByteBuf out) {\r
107         final byte SET_VLAN_VID_CODE = 1;\r
108         final byte SET_VLAN_VID_LENGTH = 8;\r
109         final byte PADDING_IN_SET_VLAN_VID_ACTION = 2;\r
110         out.writeShort(SET_VLAN_VID_CODE);\r
111         out.writeShort(SET_VLAN_VID_LENGTH);\r
112         out.writeShort(action.getAugmentation(VlanVidAction.class).getVlanVid());\r
113         ByteBufUtils.padBuffer(PADDING_IN_SET_VLAN_VID_ACTION, out);\r
114     }\r
115     \r
116     private static void encodeSetVlanPcpAction(Action action, ByteBuf out) {\r
117         final byte SET_VLAN_PCP_CODE = 2;\r
118         final byte SET_VLAN_PCP_LENGTH = 8;\r
119         final byte PADDING_IN_SET_VLAN_PCP_ACTION = 3;\r
120         out.writeShort(SET_VLAN_PCP_CODE);\r
121         out.writeShort(SET_VLAN_PCP_LENGTH);\r
122         out.writeByte(action.getAugmentation(VlanPcpAction.class).getVlanPcp());\r
123         ByteBufUtils.padBuffer(PADDING_IN_SET_VLAN_PCP_ACTION, out);\r
124     }\r
125     \r
126     private static void encodeDlAddressAction(Action action, ByteBuf out, byte code) {\r
127         final byte DL_ADDRESS_ACTION_LENGTH = 16;\r
128         final byte PADDING_IN_DL_ADDRESS_ACTION = 6;\r
129         out.writeShort(code);\r
130         out.writeShort(DL_ADDRESS_ACTION_LENGTH);\r
131         out.writeBytes(action.getAugmentation(DlAddressAction.class)\r
132                 .getDlAddress().getValue().getBytes());\r
133         ByteBufUtils.padBuffer(PADDING_IN_DL_ADDRESS_ACTION, out);\r
134     }\r
135     \r
136     private static void encodeNwTosAction(Action action, ByteBuf out) {\r
137         final byte SET_NW_TOS_CODE = 2;\r
138         final byte SET_NW_TOS_LENGTH = 8;\r
139         final byte PADDING_IN_SET_NW_TOS_ACTION = 3;\r
140         out.writeShort(SET_NW_TOS_CODE);\r
141         out.writeShort(SET_NW_TOS_LENGTH);\r
142         out.writeByte(action.getAugmentation(NwTosAction.class).getNwTos());\r
143         ByteBufUtils.padBuffer(PADDING_IN_SET_NW_TOS_ACTION, out);\r
144     }\r
145     \r
146     private static void encodeIpAddressAction(Action action, ByteBuf out, byte code) {\r
147         final byte IP_ADDRESS_ACTION_LENGTH = 8;\r
148         out.writeShort(code);\r
149         out.writeShort(IP_ADDRESS_ACTION_LENGTH);\r
150         String[] addressGroups = action.\r
151                 getAugmentation(IpAddressAction.class).getIpAddress().getValue().split(".");\r
152         for (int i = 0; i < addressGroups.length; i++) {\r
153             out.writeByte(Integer.parseInt(addressGroups[i]));\r
154         }\r
155     }\r
156     \r
157     private static void encodeTpPortAction(Action action, ByteBuf out, byte code) {\r
158         final byte TP_PORT_ACTION_LENGTH = 8;\r
159         final byte PADDING_IN_TP_PORT_ACTION = 2;\r
160         out.writeShort(code);\r
161         out.writeShort(TP_PORT_ACTION_LENGTH);\r
162         PortAction port = action.getAugmentation(PortAction.class);\r
163         out.writeShort(port.getPort().getValue().intValue());\r
164         ByteBufUtils.padBuffer(PADDING_IN_TP_PORT_ACTION, out);\r
165     }\r
166     \r
167     private static void encodeEnqueueAction(Action action, ByteBuf out) {\r
168         final byte ENQUEUE_CODE = 11;\r
169         final byte ENQUEUE_LENGTH = 16;\r
170         final byte PADDING_IN_ENQUEUE_ACTION = 6;\r
171         out.writeShort(ENQUEUE_CODE);\r
172         out.writeShort(ENQUEUE_LENGTH);\r
173         PortAction port = action.getAugmentation(PortAction.class);\r
174         out.writeShort(port.getPort().getValue().intValue());\r
175         ByteBufUtils.padBuffer(PADDING_IN_ENQUEUE_ACTION, out);\r
176         QueueIdAction queueId = action.getAugmentation(QueueIdAction.class);\r
177         out.writeShort(queueId.getQueueId().intValue());\r
178     }\r
179     \r
180     private static void encodeExperimenterAction(Action action, ByteBuf outBuffer) {\r
181         final int EXPERIMENTER_CODE = 65535; // 0xFFFF\r
182         final byte EXPERIMENTER_LENGTH = 8;\r
183         outBuffer.writeShort(EXPERIMENTER_CODE);\r
184         outBuffer.writeShort(EXPERIMENTER_LENGTH);\r
185         ExperimenterAction experimenter = action.getAugmentation(ExperimenterAction.class);\r
186         outBuffer.writeInt(experimenter.getExperimenter().intValue());\r
187     }\r
188     \r
189     /**\r
190      * Computes length of actions\r
191      * @param actionsList\r
192      * @return length of actions (OpenFlow v1.0)\r
193      */\r
194     public static int computeActionsLength(List<ActionsList> actionsList) {\r
195         int length = 0;\r
196         if (actionsList != null) {\r
197             for (ActionsList list : actionsList) {\r
198                 Action action = list.getAction();\r
199                 if (action.getType().equals(Output.class)) {\r
200                     length += 8;\r
201                 } else if (action.getType().equals(SetVlanVid.class)) {\r
202                     length += 8;\r
203                 } else if (action.getType().equals(SetVlanPcp.class)) {\r
204                     length += 8;\r
205                 } else if (action.getType().equals(StripVlan.class)) {\r
206                     length += 8;\r
207                 } else if (action.getType().equals(SetDlSrc.class)) {\r
208                     length += 16;\r
209                 } else if (action.getType().equals(SetDlDst.class)) {\r
210                     length += 16;\r
211                 } else if (action.getType().equals(SetNwSrc.class)) {\r
212                     length += 8;\r
213                 } else if (action.getType().equals(SetNwDst.class)) {\r
214                     length += 8;\r
215                 } else if (action.getType().equals(SetNwTos.class)) {\r
216                     length += 8;\r
217                 } else if (action.getType().equals(SetTpSrc.class)) {\r
218                     length += 8;\r
219                 } else if (action.getType().equals(SetTpDst.class)) {\r
220                     length += 8;\r
221                 } else if (action.getType().equals(Enqueue.class)) {\r
222                     length += 16;\r
223                 } else if (action.getType().equals(Experimenter.class)) {\r
224                     length += 8;\r
225                 }\r
226             }\r
227         }\r
228         return length;\r
229     }\r
230 \r
231 }\r