c600fbf5103c6939fc5acb62bedf330e2f686046
[openflowjava.git] / openflow-protocol-impl / src / main / java / org / opendaylight / openflowjava / protocol / impl / util / MatchDeserializer.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.ArrayList;\r
7 import java.util.List;\r
8 \r
9 import org.opendaylight.openflowjava.protocol.impl.serialization.factories.EncodeConstants;\r
10 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Dscp;\r
11 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;\r
12 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;\r
13 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6FlowLabel;\r
14 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;\r
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.BosMatchEntry;\r
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.BosMatchEntryBuilder;\r
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.DscpMatchEntry;\r
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.DscpMatchEntryBuilder;\r
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.EcnMatchEntry;\r
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.EcnMatchEntryBuilder;\r
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.EthTypeMatchEntry;\r
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.EthTypeMatchEntryBuilder;\r
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Icmpv4CodeMatchEntry;\r
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Icmpv4CodeMatchEntryBuilder;\r
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Icmpv4TypeMatchEntry;\r
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Icmpv4TypeMatchEntryBuilder;\r
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Icmpv6CodeMatchEntry;\r
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Icmpv6CodeMatchEntryBuilder;\r
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Icmpv6TypeMatchEntry;\r
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Icmpv6TypeMatchEntryBuilder;\r
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Ipv4AddressMatchEntry;\r
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Ipv4AddressMatchEntryBuilder;\r
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Ipv6AddressMatchEntry;\r
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Ipv6AddressMatchEntryBuilder;\r
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Ipv6FlabelMatchEntry;\r
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Ipv6FlabelMatchEntryBuilder;\r
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.IsidMatchEntry;\r
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.IsidMatchEntryBuilder;\r
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MacAddressMatchEntry;\r
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MacAddressMatchEntryBuilder;\r
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MaskMatchEntry;\r
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MaskMatchEntryBuilder;\r
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MetadataMatchEntry;\r
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MetadataMatchEntryBuilder;\r
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MplsLabelMatchEntry;\r
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MplsLabelMatchEntryBuilder;\r
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.OpCodeMatchEntry;\r
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.OpCodeMatchEntryBuilder;\r
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortMatchEntry;\r
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortMatchEntryBuilder;\r
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortNumberMatchEntry;\r
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortNumberMatchEntryBuilder;\r
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ProtocolNumberMatchEntry;\r
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ProtocolNumberMatchEntryBuilder;\r
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PseudoFieldMatchEntry;\r
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PseudoFieldMatchEntry.PseudoField;\r
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PseudoFieldMatchEntryBuilder;\r
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.TcMatchEntry;\r
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.TcMatchEntryBuilder;\r
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.VlanPcpMatchEntry;\r
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.VlanPcpMatchEntryBuilder;\r
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.VlanVidMatchEntry;\r
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.VlanVidMatchEntryBuilder;\r
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.EtherType;\r
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber;\r
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.StandardMatchType;\r
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.ArpOp;\r
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.ArpSha;\r
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.ArpSpa;\r
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.ArpTha;\r
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.ArpTpa;\r
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.EthDst;\r
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.EthSrc;\r
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.EthType;\r
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.ExperimenterClass;\r
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Icmpv4Code;\r
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Icmpv4Type;\r
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Icmpv6Code;\r
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Icmpv6Type;\r
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.InPhyPort;\r
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.InPort;\r
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.IpDscp;\r
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.IpEcn;\r
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.IpProto;\r
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv4Dst;\r
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv4Src;\r
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv6Dst;\r
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv6Exthdr;\r
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv6Flabel;\r
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv6NdSll;\r
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv6NdTarget;\r
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv6NdTll;\r
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv6Src;\r
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Metadata;\r
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.MplsBos;\r
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.MplsLabel;\r
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.MplsTc;\r
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Nxm0Class;\r
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Nxm1Class;\r
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.OpenflowBasicClass;\r
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.OxmMatchType;\r
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.PbbIsid;\r
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.SctpDst;\r
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.SctpSrc;\r
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.TcpDst;\r
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.TcpSrc;\r
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.TunnelId;\r
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.UdpDst;\r
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.UdpSrc;\r
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.VlanPcp;\r
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.VlanVid;\r
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.MatchEntries;\r
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.MatchEntriesBuilder;\r
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.match.grouping.Match;\r
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.match.grouping.MatchBuilder;\r
116 import org.slf4j.Logger;\r
117 import org.slf4j.LoggerFactory;\r
118 \r
119 import com.google.common.base.Joiner;\r
120 \r
121 /**\r
122  * Class for easy creation of matches\r
123  * @author timotej.kubas\r
124  * @author michal.polkorab\r
125  */\r
126 public abstract class MatchDeserializer {\r
127     private static final Logger LOGGER = LoggerFactory.getLogger(MatchDeserializer.class);\r
128     private static final byte SIZE_OF_LONG_IN_BYTES = Long.SIZE / Byte.SIZE;\r
129     private static final byte SIZE_OF_INT_IN_BYTES = Integer.SIZE / Byte.SIZE;\r
130     private static final byte SIZE_OF_SHORT_IN_BYTES = Short.SIZE / Byte.SIZE;\r
131     private static final byte SIZE_OF_BYTE_IN_BYTES = Byte.SIZE / Byte.SIZE;\r
132     private static final byte SIZE_OF_IPV6_ADDRESS_IN_BYTES = (8 * Short.SIZE) / Byte.SIZE;\r
133     private static List<MatchEntries> matchEntriesList = new ArrayList<>();\r
134     private static MatchEntriesBuilder matchEntriesBuilder = new MatchEntriesBuilder(); \r
135     \r
136     /**\r
137      * Creates match\r
138      * @param in inputu ByteBuf\r
139      * @return ofp_match\r
140      */\r
141     public static Match createMatch(ByteBuf in) {\r
142         if (in.readableBytes() > 0) {\r
143             MatchBuilder builder = new MatchBuilder();\r
144             int type = in.readUnsignedShort();\r
145             int length = in.readUnsignedShort();\r
146             LOGGER.debug("length: " + length);\r
147             switch (type) {\r
148             case 0:\r
149                 builder.setType(StandardMatchType.class);\r
150                 break;\r
151             case 1:\r
152                 builder.setType(OxmMatchType.class);\r
153                 break;\r
154             default:\r
155                 break;\r
156             }\r
157             builder.setMatchEntries(createMatchEntries(in, length - 2 * (Short.SIZE / Byte.SIZE)));\r
158             int paddingRemainder = length % EncodeConstants.PADDING;\r
159             if (paddingRemainder != 0) {\r
160                 in.skipBytes(paddingRemainder);\r
161             }\r
162             return builder.build();\r
163         }\r
164         return null;\r
165     }\r
166     \r
167     /**\r
168      * @param in input ByteBuf\r
169      * @param matchArrayLength to infer size of array\r
170      * @return MatchEntriesList\r
171      */\r
172     public static List<MatchEntries> createMatchEntries(ByteBuf in, int matchArrayLength) {\r
173         int currMatchLength = 0;\r
174         LOGGER.debug("createMatchEntries");\r
175         LOGGER.debug("matcharraylength: " + matchArrayLength);\r
176         while(currMatchLength < matchArrayLength) {\r
177             LOGGER.debug("creating new match entry");\r
178             switch (in.readUnsignedShort()) { \r
179             case 0x0000:\r
180                         matchEntriesBuilder.setOxmClass(Nxm0Class.class);\r
181                         break;\r
182             case 0x0001:\r
183                         matchEntriesBuilder.setOxmClass(Nxm1Class.class);\r
184                         break;\r
185             case 0x8000:\r
186                         matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
187                         LOGGER.debug("ofbasicclass");\r
188                         break;\r
189             case 0xFFFF:\r
190                         matchEntriesBuilder.setOxmClass(ExperimenterClass.class);\r
191                         break;\r
192             default:\r
193                         break;\r
194             }\r
195 \r
196             int matchField = in.readUnsignedByte() >>> 1;\r
197             short matchEntryLength = in.readUnsignedByte();\r
198             currMatchLength = currMatchLength + SIZE_OF_SHORT_IN_BYTES + (2 * SIZE_OF_BYTE_IN_BYTES) + matchEntryLength;\r
199             \r
200             switch(matchField) {\r
201             case 0: \r
202                 matchEntriesBuilder.setOxmMatchField(InPort.class);\r
203                 PortNumberMatchEntryBuilder port = new PortNumberMatchEntryBuilder();\r
204                 port.setPortNumber(new PortNumber(in.readUnsignedInt())); \r
205                 matchEntriesBuilder.addAugmentation(PortNumberMatchEntry.class, port.build());\r
206                 break;\r
207             case 1:\r
208                 matchEntriesBuilder.setOxmMatchField(InPhyPort.class);\r
209                 PortNumberMatchEntryBuilder phyPort = new PortNumberMatchEntryBuilder();\r
210                 phyPort.setPortNumber(new PortNumber(in.readUnsignedInt())); \r
211                 matchEntriesBuilder.addAugmentation(PortNumberMatchEntry.class, phyPort.build());\r
212                 break;\r
213             case 2:\r
214                 matchEntriesBuilder.setOxmMatchField(Metadata.class);\r
215                 addMetadataAugmentation(matchEntriesBuilder, in);\r
216                 matchEntryLength -= SIZE_OF_LONG_IN_BYTES;\r
217                 if (matchEntryLength > 0) {\r
218                     addMaskAugmentation(matchEntriesBuilder, in, matchEntryLength);\r
219                 }\r
220                 break;\r
221             case 3:\r
222                 matchEntriesBuilder.setOxmMatchField(EthDst.class);\r
223                 addMacAddressAugmentation(matchEntriesBuilder, in);\r
224                 matchEntryLength -= SIZE_OF_LONG_IN_BYTES;\r
225                 if (matchEntryLength > 0) {\r
226                     addMaskAugmentation(matchEntriesBuilder, in, matchEntryLength);\r
227                 }\r
228                 break;\r
229             case 4:\r
230                 matchEntriesBuilder.setOxmMatchField(EthSrc.class);\r
231                 addMacAddressAugmentation(matchEntriesBuilder, in);\r
232                 matchEntryLength -= SIZE_OF_LONG_IN_BYTES;\r
233                 if (matchEntryLength > 0) {\r
234                     addMaskAugmentation(matchEntriesBuilder, in, matchEntryLength);\r
235                 }\r
236                 break;\r
237             case 5:\r
238                 matchEntriesBuilder.setOxmMatchField(EthType.class);\r
239                 EthTypeMatchEntryBuilder ethertypeBuilder = new EthTypeMatchEntryBuilder();\r
240                 ethertypeBuilder.setEthType(new EtherType(in.readUnsignedShort()));\r
241                 matchEntriesBuilder.addAugmentation(EthTypeMatchEntry.class, ethertypeBuilder.build());\r
242                 break;\r
243             case 6:\r
244                 matchEntriesBuilder.setOxmMatchField(VlanVid.class);\r
245                 VlanVidMatchEntryBuilder vlanVidBuilder = new VlanVidMatchEntryBuilder();\r
246                 int vidEntryValue = in.readUnsignedShort(); \r
247                 vlanVidBuilder.setCfiBit((vidEntryValue & 1) != 0);\r
248                 vlanVidBuilder.setVlanVid(vidEntryValue >> 1);\r
249                 matchEntriesBuilder.addAugmentation(VlanVidMatchEntry.class, vlanVidBuilder.build());\r
250                 matchEntryLength -= SIZE_OF_SHORT_IN_BYTES;\r
251                 if (matchEntryLength > 0) {\r
252                     addMaskAugmentation(matchEntriesBuilder, in, matchEntryLength);\r
253                 }\r
254                 break;\r
255             case 7:\r
256                 matchEntriesBuilder.setOxmMatchField(VlanPcp.class);\r
257                 VlanPcpMatchEntryBuilder vlanPcpBuilder = new VlanPcpMatchEntryBuilder();\r
258                 vlanPcpBuilder.setVlanPcp(in.readUnsignedByte());\r
259                 matchEntriesBuilder.addAugmentation(VlanPcpMatchEntry.class, vlanPcpBuilder.build());\r
260                 break;\r
261             case 8:\r
262                 matchEntriesBuilder.setOxmMatchField(IpDscp.class);\r
263                 DscpMatchEntryBuilder dscpBuilder = new DscpMatchEntryBuilder();\r
264                 dscpBuilder.setDscp(new Dscp(in.readUnsignedByte()));\r
265                 matchEntriesBuilder.addAugmentation(DscpMatchEntry.class, dscpBuilder.build());\r
266                 break;\r
267             case 9:\r
268                 matchEntriesBuilder.setOxmMatchField(IpEcn.class);\r
269                 EcnMatchEntryBuilder ecnBuilder = new EcnMatchEntryBuilder();\r
270                 ecnBuilder.setEcn(in.readUnsignedByte());\r
271                 matchEntriesBuilder.addAugmentation(EcnMatchEntry.class, ecnBuilder.build());\r
272                 break;\r
273             case 10:\r
274                 matchEntriesBuilder.setOxmMatchField(IpProto.class);\r
275                 ProtocolNumberMatchEntryBuilder protoNumberBuilder = new ProtocolNumberMatchEntryBuilder();\r
276                 protoNumberBuilder.setProtocolNumber(in.readUnsignedByte());\r
277                 matchEntriesBuilder.addAugmentation(ProtocolNumberMatchEntry.class, protoNumberBuilder.build());\r
278                 break;\r
279             case 11:\r
280                 matchEntriesBuilder.setOxmMatchField(Ipv4Src.class);\r
281                 // TODO - ipv4address - check format with tests\r
282                 LOGGER.warn("IPV4address(ipv4src): received but possible wrong deserialization");\r
283                 addIpv4AddressAugmentation(matchEntriesBuilder, in);\r
284                 matchEntryLength -= SIZE_OF_INT_IN_BYTES;\r
285                 if (matchEntryLength > 0) {\r
286                     addMaskAugmentation(matchEntriesBuilder, in, matchEntryLength);\r
287                 }\r
288                 break;\r
289             case 12:\r
290                 matchEntriesBuilder.setOxmMatchField(Ipv4Dst.class);\r
291                 // TODO - ipv4address - check format with tests\r
292                 LOGGER.warn("IPV4address(ipv4dst): received but possible wrong deserialization");\r
293                 addIpv4AddressAugmentation(matchEntriesBuilder, in);\r
294                 matchEntryLength -= SIZE_OF_INT_IN_BYTES;\r
295                 if (matchEntryLength > 0) {\r
296                     addMaskAugmentation(matchEntriesBuilder, in, matchEntryLength);\r
297                 }\r
298                 break;\r
299             case 13:\r
300                 matchEntriesBuilder.setOxmMatchField(TcpSrc.class);\r
301                 addPortAugmentation(null, in);\r
302                 break;\r
303             case 14:\r
304                 matchEntriesBuilder.setOxmMatchField(TcpDst.class);\r
305                 addPortAugmentation(null, in);\r
306                 break;\r
307             case 15:\r
308                 matchEntriesBuilder.setOxmMatchField(UdpSrc.class);\r
309                 addPortAugmentation(null, in);\r
310                 break;\r
311             case 16:\r
312                 matchEntriesBuilder.setOxmMatchField(UdpDst.class);\r
313                 addPortAugmentation(null, in);\r
314                 break;\r
315             case 17:\r
316                 matchEntriesBuilder.setOxmMatchField(SctpSrc.class);\r
317                 addPortAugmentation(null, in);\r
318                 break;\r
319             case 18:\r
320                 matchEntriesBuilder.setOxmMatchField(SctpDst.class);\r
321                 addPortAugmentation(null, in);\r
322                 break;\r
323             case 19:\r
324                 matchEntriesBuilder.setOxmMatchField(Icmpv4Type.class);\r
325                 Icmpv4TypeMatchEntryBuilder icmpv4TypeBuilder = new Icmpv4TypeMatchEntryBuilder();\r
326                 icmpv4TypeBuilder.setIcmpv4Type(in.readUnsignedByte());\r
327                 matchEntriesBuilder.addAugmentation(Icmpv4TypeMatchEntry.class, icmpv4TypeBuilder.build());\r
328                 break;\r
329             case 20:\r
330                 matchEntriesBuilder.setOxmMatchField(Icmpv4Code.class);\r
331                 Icmpv4CodeMatchEntryBuilder icmpv4CodeBuilder = new Icmpv4CodeMatchEntryBuilder();\r
332                 icmpv4CodeBuilder.setIcmpv4Code(in.readUnsignedByte());\r
333                 matchEntriesBuilder.addAugmentation(Icmpv4CodeMatchEntry.class, icmpv4CodeBuilder.build());\r
334                 break;\r
335             case 21:\r
336                 matchEntriesBuilder.setOxmMatchField(ArpOp.class);\r
337                 OpCodeMatchEntryBuilder opcodeBuilder = new OpCodeMatchEntryBuilder();\r
338                 opcodeBuilder.setOpCode(in.readUnsignedShort());\r
339                 matchEntriesBuilder.addAugmentation(OpCodeMatchEntry.class, opcodeBuilder.build());\r
340                 break;\r
341             case 22:\r
342                 matchEntriesBuilder.setOxmMatchField(ArpSpa.class);\r
343                 // TODO - ipv4address - check format with tests\r
344                 LOGGER.warn("IPV4address(arpspa): received but possible wrong deserialization");\r
345                 addIpv4AddressAugmentation(matchEntriesBuilder, in);\r
346                 matchEntryLength -= SIZE_OF_INT_IN_BYTES;\r
347                 if (matchEntryLength > 0) {\r
348                     addMaskAugmentation(matchEntriesBuilder, in, matchEntryLength);\r
349                 }\r
350                 break;\r
351             case 23:\r
352                 matchEntriesBuilder.setOxmMatchField(ArpTpa.class);\r
353                 // TODO - ipv4address - check format with tests\r
354                 LOGGER.warn("IPV4address(arptpa): received but possible wrong deserialization");\r
355                 addIpv4AddressAugmentation(matchEntriesBuilder, in);\r
356                 matchEntryLength -= SIZE_OF_INT_IN_BYTES;\r
357                 if (matchEntryLength > 0) {\r
358                     addMaskAugmentation(matchEntriesBuilder, in, matchEntryLength);\r
359                 }\r
360                 break;\r
361             case 24:\r
362                 matchEntriesBuilder.setOxmMatchField(ArpSha.class);\r
363                 addMacAddressAugmentation(matchEntriesBuilder, in);\r
364                 matchEntryLength -= SIZE_OF_LONG_IN_BYTES;\r
365                 if (matchEntryLength > 0) {\r
366                     addMaskAugmentation(matchEntriesBuilder, in, matchEntryLength);\r
367                 }\r
368                 break;\r
369             case 25:\r
370                 matchEntriesBuilder.setOxmMatchField(ArpTha.class);\r
371                 addMacAddressAugmentation(matchEntriesBuilder, in);\r
372                 matchEntryLength -= SIZE_OF_LONG_IN_BYTES;\r
373                 if (matchEntryLength > 0) {\r
374                     addMaskAugmentation(matchEntriesBuilder, in, matchEntryLength);\r
375                 }\r
376                 break;\r
377             case 26:\r
378                 matchEntriesBuilder.setOxmMatchField(Ipv6Src.class);\r
379                 // TODO - ipv6address - check format with tests\r
380                 LOGGER.warn("IPV6address(Ipv6Src): received but possible wrong deserialization");\r
381                 addIpv6AddressAugmentation(matchEntriesBuilder, in);\r
382                 matchEntryLength -= SIZE_OF_IPV6_ADDRESS_IN_BYTES;\r
383                 if (matchEntryLength > 0) {\r
384                     addMaskAugmentation(matchEntriesBuilder, in, matchEntryLength);\r
385                 }\r
386                 break;\r
387             case 27:\r
388                 matchEntriesBuilder.setOxmMatchField(Ipv6Dst.class);\r
389                 // TODO - ipv6address - check format with tests\r
390                 LOGGER.warn("IPV6address(Ipv6Dst): received but possible wrong deserialization");\r
391                 addIpv6AddressAugmentation(matchEntriesBuilder, in);\r
392                 matchEntryLength -= SIZE_OF_IPV6_ADDRESS_IN_BYTES;\r
393                 if (matchEntryLength > 0) {\r
394                     addMaskAugmentation(matchEntriesBuilder, in, matchEntryLength);\r
395                 }\r
396                 break;\r
397             case 28:\r
398                 matchEntriesBuilder.setOxmMatchField(Ipv6Flabel.class);\r
399                 Ipv6FlabelMatchEntryBuilder ipv6FlabelBuilder = new Ipv6FlabelMatchEntryBuilder();\r
400                 ipv6FlabelBuilder.setIpv6Flabel(new Ipv6FlowLabel(in.readUnsignedInt()));\r
401                 matchEntriesBuilder.addAugmentation(Ipv6FlabelMatchEntry.class, ipv6FlabelBuilder.build());\r
402                 matchEntryLength -= SIZE_OF_INT_IN_BYTES;\r
403                 if (matchEntryLength > 0) {\r
404                     addMaskAugmentation(matchEntriesBuilder, in, matchEntryLength);\r
405                 }\r
406                 break;\r
407             case 29:\r
408                 matchEntriesBuilder.setOxmMatchField(Icmpv6Type.class);\r
409                 Icmpv6TypeMatchEntryBuilder icmpv6TypeBuilder = new Icmpv6TypeMatchEntryBuilder();\r
410                 icmpv6TypeBuilder.setIcmpv6Type(in.readUnsignedByte());\r
411                 matchEntriesBuilder.addAugmentation(Icmpv6TypeMatchEntry.class, icmpv6TypeBuilder.build());\r
412                 break;\r
413             case 30:\r
414                 matchEntriesBuilder.setOxmMatchField(Icmpv6Code.class);\r
415                 Icmpv6CodeMatchEntryBuilder icmpv6CodeBuilder = new Icmpv6CodeMatchEntryBuilder();\r
416                 icmpv6CodeBuilder.setIcmpv6Code(in.readUnsignedByte());\r
417                 matchEntriesBuilder.addAugmentation(Icmpv6CodeMatchEntry.class, icmpv6CodeBuilder.build());\r
418                 break;\r
419             case 31:\r
420                 matchEntriesBuilder.setOxmMatchField(Ipv6NdTarget.class);\r
421                 // TODO - ipv6address - check format with tests\r
422                 LOGGER.warn("IPV6address(Ipv6NdTarget): received but possible wrong deserialization");\r
423                 addIpv6AddressAugmentation(matchEntriesBuilder, in);\r
424                 break;\r
425             case 32:\r
426                 matchEntriesBuilder.setOxmMatchField(Ipv6NdSll.class);\r
427                 addMacAddressAugmentation(matchEntriesBuilder, in);\r
428                 break;\r
429             case 33:\r
430                 matchEntriesBuilder.setOxmMatchField(Ipv6NdTll.class);\r
431                 addMacAddressAugmentation(matchEntriesBuilder, in);\r
432                 break;\r
433             case 34:\r
434                 matchEntriesBuilder.setOxmMatchField(MplsLabel.class);\r
435                 MplsLabelMatchEntryBuilder mplsLabelBuilder = new MplsLabelMatchEntryBuilder();\r
436                 mplsLabelBuilder.setMplsLabel(in.readUnsignedInt());\r
437                 matchEntriesBuilder.addAugmentation(MplsLabelMatchEntry.class, mplsLabelBuilder.build());\r
438                 break;\r
439             case 35:\r
440                 matchEntriesBuilder.setOxmMatchField(MplsTc.class);\r
441                 TcMatchEntryBuilder tcBuilder = new TcMatchEntryBuilder();\r
442                 tcBuilder.setTc(in.readUnsignedByte());\r
443                 matchEntriesBuilder.addAugmentation(TcMatchEntry.class, tcBuilder.build());\r
444                 break;\r
445             case 36:\r
446                 matchEntriesBuilder.setOxmMatchField(MplsBos.class);\r
447                 BosMatchEntryBuilder bosBuilder = new BosMatchEntryBuilder();\r
448                 if (in.readUnsignedByte() != 0) {\r
449                     bosBuilder.setBos(true);\r
450                 } else {\r
451                     bosBuilder.setBos(false);\r
452                 }\r
453                 matchEntriesBuilder.addAugmentation(BosMatchEntry.class, bosBuilder.build());\r
454                 break;\r
455             case 37:\r
456                 matchEntriesBuilder.setOxmMatchField(PbbIsid.class);\r
457                 IsidMatchEntryBuilder isidBuilder = new IsidMatchEntryBuilder();\r
458                 isidBuilder.setIsid(in.readUnsignedInt());\r
459                 matchEntriesBuilder.addAugmentation(IsidMatchEntry.class, isidBuilder.build());\r
460                 matchEntryLength -= SIZE_OF_INT_IN_BYTES;\r
461                 if (matchEntryLength > 0) {\r
462                     addMaskAugmentation(matchEntriesBuilder, in, matchEntryLength);\r
463                 }\r
464                 break;\r
465             case 38:\r
466                 matchEntriesBuilder.setOxmMatchField(TunnelId.class);\r
467                 addMetadataAugmentation(matchEntriesBuilder, in);\r
468                 matchEntryLength -= SIZE_OF_LONG_IN_BYTES;\r
469                 if (matchEntryLength > 0) {\r
470                     addMaskAugmentation(matchEntriesBuilder, in, matchEntryLength);\r
471                 }\r
472                 break;\r
473             case 39:\r
474                 matchEntriesBuilder.setOxmMatchField(Ipv6Exthdr.class);\r
475                 PseudoFieldMatchEntryBuilder pseudoBuilder = new PseudoFieldMatchEntryBuilder();\r
476                 int bitmap = in.readUnsignedShort();\r
477                 final Boolean NONEXT = ((bitmap) & (1<<0)) != 0;\r
478                 final Boolean ESP = ((bitmap) & (1<<1)) != 0;\r
479                 final Boolean AUTH = ((bitmap) & (1<<2)) != 0;\r
480                 final Boolean DEST = ((bitmap) & (1<<3)) != 0;\r
481                 final Boolean FRAG = ((bitmap) & (1<<4)) != 0;\r
482                 final Boolean ROUTER = ((bitmap) & (1<<5)) != 0;\r
483                 final Boolean HOP = ((bitmap) & (1<<6)) != 0;\r
484                 final Boolean UNREP = ((bitmap) & (1<<7)) != 0;\r
485                 final Boolean UNSEQ = ((bitmap) & (1<<8)) != 0;\r
486                 pseudoBuilder.setPseudoField(new PseudoField(AUTH, DEST, ESP, FRAG, HOP, NONEXT, ROUTER, UNREP, UNSEQ));\r
487                 matchEntriesBuilder.addAugmentation(PseudoFieldMatchEntry.class, pseudoBuilder.build());\r
488                 matchEntryLength -= SIZE_OF_SHORT_IN_BYTES;\r
489                 if (matchEntryLength > 0) {\r
490                     addMaskAugmentation(matchEntriesBuilder, in, matchEntryLength);\r
491                 }\r
492                 break;\r
493             default: \r
494                 break;\r
495             }\r
496           matchEntriesList.add(matchEntriesBuilder.build());\r
497         }\r
498         return matchEntriesList;\r
499     }\r
500 \r
501     private static void addMaskAugmentation(MatchEntriesBuilder builder, ByteBuf in, int matchEntryLength) {\r
502 //         TODO - check if matchEntryLength is in bytes\r
503         MaskMatchEntryBuilder maskBuilder = new MaskMatchEntryBuilder();\r
504         byte[] mask = new byte[matchEntryLength];\r
505         in.readBytes(mask);\r
506         maskBuilder.setMask(mask);\r
507         builder.addAugmentation(MaskMatchEntry.class, maskBuilder.build());\r
508     }\r
509 \r
510     private static void addIpv6AddressAugmentation(MatchEntriesBuilder builder, ByteBuf in) {\r
511         final byte GROUPS_IN_IPV6_ADDRESS = 8;\r
512         Ipv6AddressMatchEntryBuilder ipv6AddressBuilder = new Ipv6AddressMatchEntryBuilder();\r
513         List<String> groups = new ArrayList<>();\r
514         for (int i = 0; i < GROUPS_IN_IPV6_ADDRESS; i++) {\r
515             groups.add(String.format("X", in.readUnsignedShort()));\r
516         }\r
517         Joiner joiner = Joiner.on(":");\r
518         ipv6AddressBuilder.setIpv6Address(new Ipv6Address(joiner.join(groups)));\r
519         builder.addAugmentation(Ipv6AddressMatchEntry.class, ipv6AddressBuilder.build());\r
520     }\r
521     \r
522     private static void addMetadataAugmentation(MatchEntriesBuilder builder, ByteBuf in) {\r
523         MetadataMatchEntryBuilder metadata = new MetadataMatchEntryBuilder();\r
524         byte[] metadataBytes = new byte[Long.SIZE/Byte.SIZE];\r
525         in.readBytes(metadataBytes);\r
526         metadata.setMetadata(metadataBytes); \r
527         builder.addAugmentation(MetadataMatchEntry.class, metadata.build());\r
528     }\r
529 \r
530     private static void addIpv4AddressAugmentation(MatchEntriesBuilder builder, ByteBuf in) {\r
531         final byte GROUPS_IN_IPV4_ADDRESS = 4;\r
532         Ipv4AddressMatchEntryBuilder ipv4AddressBuilder = new Ipv4AddressMatchEntryBuilder();\r
533         List<String> groups = new ArrayList<>();\r
534         for (int i = 0; i < GROUPS_IN_IPV4_ADDRESS; i++) {\r
535             groups.add(Short.toString(in.readUnsignedByte()));\r
536         }\r
537         Joiner joiner = Joiner.on(".");\r
538         ipv4AddressBuilder.setIpv4Address(new Ipv4Address(joiner.join(groups)));\r
539         builder.addAugmentation(Ipv4AddressMatchEntry.class, ipv4AddressBuilder.build());\r
540     }\r
541 \r
542     private static void addMacAddressAugmentation(MatchEntriesBuilder builder, ByteBuf in) {\r
543         MacAddressMatchEntryBuilder macAddress = new MacAddressMatchEntryBuilder();\r
544         StringBuffer macToString = new StringBuffer();\r
545         final int macAddressLength = 6;\r
546         for(int i=0; i<macAddressLength ; i++){\r
547             short mac = 0;\r
548             mac = in.readUnsignedByte();\r
549             macToString.append(String.format("%02X", mac));\r
550         }\r
551         macAddress.setMacAddress(new MacAddress(macToString.toString())); \r
552         builder.addAugmentation(MacAddressMatchEntry.class, macAddress.build());\r
553     }\r
554     \r
555     private static void addPortAugmentation(MatchEntriesBuilder builder, ByteBuf in) {\r
556         PortMatchEntryBuilder portBuilder = new PortMatchEntryBuilder();\r
557         portBuilder.setPort(new org.opendaylight.yang.gen.v1.urn.ietf.params.\r
558                 xml.ns.yang.ietf.inet.types.rev100924.PortNumber(in.readUnsignedShort()));\r
559         builder.addAugmentation(PortMatchEntry.class, portBuilder.build());\r
560     }\r
561 }\r