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