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