Merge "OF1.3 matchSerializer (Ipv6 address) fix + test"
[openflowjava.git] / openflow-protocol-impl / src / main / java / org / opendaylight / openflowjava / protocol / impl / util / OF10MatchDeserializer.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.Ipv4Address;\r
10 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;\r
11 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowWildcardsV10;\r
12 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.match.v10.grouping.MatchV10;\r
13 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.match.v10.grouping.MatchV10Builder;\r
14 \r
15 import com.google.common.base.Joiner;\r
16 \r
17 /**\r
18  * Deserializes ofp_match (OpenFlow v1.0) structure\r
19  * @author michal.polkorab\r
20  */\r
21 public abstract class OF10MatchDeserializer {\r
22     \r
23     private static final byte PADDING_IN_MATCH = 1;\r
24     private static final byte PADDING_IN_MATCH_2 = 2;\r
25     private static final byte NW_SRC_BITS = 6;\r
26     private static final byte NW_SRC_SHIFT = 8;\r
27     private static final int NW_SRC_MASK = ((1 << NW_SRC_BITS) - 1) << NW_SRC_SHIFT;\r
28     private static final byte NW_DST_BITS = 6;\r
29     private static final byte NW_DST_SHIFT = 14;\r
30     private static final int NW_DST_MASK = ((1 << NW_DST_BITS) - 1) << NW_DST_SHIFT;\r
31 \r
32     /**\r
33      * Creates ofp_match (OpenFlow v1.0) structure\r
34      * @param rawMessage ByteBuf with input data\r
35      * @return ofp_match (OpenFlow v1.0)\r
36      */\r
37     public static MatchV10 createMatchV10(ByteBuf rawMessage) {\r
38         MatchV10Builder builder = new MatchV10Builder();\r
39         long wildcards = rawMessage.readUnsignedInt();\r
40         builder.setWildcards(createWildcards(wildcards));\r
41         builder.setNwSrcMask(decodeNwSrcMask(wildcards));\r
42         builder.setNwDstMask(decodeNwDstMask(wildcards));\r
43         builder.setInPort(rawMessage.readUnsignedShort());\r
44         byte[] dlSrc = new byte[EncodeConstants.MAC_ADDRESS_LENGTH];\r
45         rawMessage.readBytes(dlSrc);\r
46         builder.setDlSrc(new MacAddress(ByteBufUtils.macAddressToString(dlSrc)));\r
47         byte[] dlDst = new byte[EncodeConstants.MAC_ADDRESS_LENGTH];\r
48         rawMessage.readBytes(dlDst);\r
49         builder.setDlDst(new MacAddress(ByteBufUtils.macAddressToString(dlDst)));\r
50 \r
51         builder.setDlVlan(rawMessage.readUnsignedShort());\r
52         builder.setDlVlanPcp(rawMessage.readUnsignedByte());\r
53         rawMessage.skipBytes(PADDING_IN_MATCH);\r
54         builder.setDlType(rawMessage.readUnsignedShort());\r
55         builder.setNwTos(rawMessage.readUnsignedByte());\r
56         builder.setNwProto(rawMessage.readUnsignedByte());\r
57         rawMessage.skipBytes(PADDING_IN_MATCH_2);\r
58         List<String> srcGroups = new ArrayList<>();\r
59         for (int i = 0; i < EncodeConstants.GROUPS_IN_IPV4_ADDRESS; i++) {\r
60             srcGroups.add(Short.toString(rawMessage.readUnsignedByte()));\r
61         }\r
62         Joiner joiner = Joiner.on(".");\r
63         builder.setNwSrc(new Ipv4Address(joiner.join(srcGroups)));\r
64         List<String> dstGroups = new ArrayList<>();\r
65         for (int i = 0; i < EncodeConstants.GROUPS_IN_IPV4_ADDRESS; i++) {\r
66             dstGroups.add(Short.toString(rawMessage.readUnsignedByte()));\r
67         }\r
68         builder.setNwDst(new Ipv4Address(joiner.join(dstGroups)));\r
69         builder.setTpSrc(rawMessage.readUnsignedShort());\r
70         builder.setTpDst(rawMessage.readUnsignedShort());\r
71         return builder.build();\r
72     }\r
73     \r
74     private static FlowWildcardsV10 createWildcards(long input) {\r
75         boolean _iNPORT = (input & (1 << 0)) != 0;\r
76         boolean _dLVLAN = (input & (1 << 1)) != 0;\r
77         boolean _dLSRC = (input & (1 << 2)) != 0;\r
78         boolean _dLDST = (input & (1 << 3)) != 0;\r
79         boolean _dLTYPE = (input & (1 << 4)) != 0;\r
80         boolean _nWPROTO = (input & (1 << 5)) != 0;\r
81         boolean _tPSRC = (input & (1 << 6)) != 0;\r
82         boolean _tPDST = (input & (1 << 7)) != 0;\r
83         boolean _dLVLANPCP = (input & (1 << 20)) != 0;\r
84         boolean _nWTOS = (input & (1 << 21)) != 0;\r
85         int allBits = (1 << 22) - 1;\r
86         boolean _aLL = (input & allBits) == allBits;\r
87         return new FlowWildcardsV10(_aLL, _dLDST, _dLSRC, _dLTYPE, _dLVLAN,\r
88                 _dLVLANPCP, _iNPORT, _nWPROTO, _nWTOS, _tPDST, _tPSRC);\r
89     }\r
90     \r
91     private static short decodeNwSrcMask(long input) {\r
92         return (short) Math.max(32 - ((input & NW_SRC_MASK) >> NW_SRC_SHIFT), 0);\r
93     }\r
94     \r
95     private static short decodeNwDstMask(long input) {\r
96         return (short) Math.max(32 - ((input & NW_DST_MASK) >> NW_DST_SHIFT), 0);\r
97     }\r
98     \r
99 }\r