Merge "Fix checkstyle warnings for impl/datastore package"
[openflowplugin.git] / openflowplugin-impl / src / main / java / org / opendaylight / openflowplugin / impl / protocol / serialization / match / AbstractMatchEntrySerializer.java
1 /*
2  * Copyright (c) 2016 Pantheon Technologies s.r.o. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.openflowplugin.impl.protocol.serialization.match;
10
11 import io.netty.buffer.ByteBuf;
12 import java.util.Iterator;
13 import java.util.Optional;
14 import org.opendaylight.openflowjava.protocol.api.extensibility.HeaderSerializer;
15 import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
16 import org.opendaylight.openflowplugin.api.openflow.protocol.serialization.MatchEntrySerializer;
17 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.common.IpConversionUtil;
18 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.match.MatchConvertorUtil;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.IetfYangUtil;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.Match;
27
28 public abstract class AbstractMatchEntrySerializer implements HeaderSerializer<Match>, MatchEntrySerializer {
29
30     @Override
31     public void serialize(Match match, ByteBuf outBuffer) {
32         serializeHeader(match, outBuffer);
33     }
34
35     @Override
36     public void serializeHeader(Match match, ByteBuf outBuffer) {
37         outBuffer.writeShort(getOxmClassCode());
38
39         int fieldAndMask = getOxmFieldCode() << 1;
40         int length = getValueLength();
41
42         if (getHasMask(match)) {
43             fieldAndMask |= 1;
44             length *= 2;
45         }
46
47         outBuffer.writeByte(fieldAndMask);
48         outBuffer.writeByte(length);
49     }
50
51     /**
52      * Serialize byte mask to bytes. checking for mask length.
53      *
54      * @param mask byte mask
55      * @param outBuffer output buffer
56      * @param length mask length
57      */
58     protected static void writeMask(byte[] mask, ByteBuf outBuffer, int length) {
59         if (mask != null && mask.length != length) {
60             throw new IllegalArgumentException("incorrect length of mask: "
61                     + mask.length + ", expected: " + length);
62         }
63
64         outBuffer.writeBytes(mask);
65     }
66
67     /**
68      * Serialize Ipv4 address to bytes.
69      *
70      * @param address Ipv4 address
71      * @param outBuffer output buffer
72      */
73     protected static void writeIpv4Address(final Ipv4Address address, final ByteBuf outBuffer) {
74         outBuffer.writeBytes(IetfInetUtil.INSTANCE.ipv4AddressBytes(address));
75     }
76
77     /**
78      * Serialize Ipv6 address to bytes.
79      *
80      * @param address Ipv6 address
81      * @param outBuffer output buffer
82      */
83     protected static void writeIpv6Address(final Ipv6Address address, final ByteBuf outBuffer) {
84         outBuffer.writeBytes(IetfInetUtil.INSTANCE.ipv6AddressBytes(address));
85     }
86
87     /**
88      * Serialize Mac address to bytes.
89      *
90      * @param address Mac address
91      * @param outBuffer output buffer
92      */
93     protected static void writeMacAddress(final MacAddress address, final ByteBuf outBuffer) {
94         outBuffer.writeBytes(IetfYangUtil.INSTANCE.bytesFor(address)); // 48 b + mask [OF 1.3.2 spec]
95     }
96
97     /**
98      * Serialize Ipv4 prefix (address and mask).
99      *
100      * @param prefix Ipv4 prefix
101      * @param outBuffer output buffer
102      */
103     protected static void writeIpv4Prefix(final Ipv4Prefix prefix, final ByteBuf outBuffer) {
104         // Split address to IP and mask
105         final Iterator<String> addressParts = IpConversionUtil.splitToParts(prefix);
106
107         // Write address part of prefix
108         writeIpv4Address(new Ipv4Address(addressParts.next()), outBuffer);
109
110         // If prefix had mask, also write prefix
111         Optional.ofNullable(MatchConvertorUtil.extractIpv4Mask(addressParts)).ifPresent(mask ->
112                 writeMask(mask, outBuffer, EncodeConstants.GROUPS_IN_IPV4_ADDRESS));
113     }
114
115     /**
116      * Serialize Ipv6 prefix (address and mask).
117      *
118      * @param prefix Ipv6 prefix
119      * @param outBuffer output buffer
120      */
121     protected static void writeIpv6Prefix(final Ipv6Prefix prefix, final ByteBuf outBuffer) {
122         // Write address part of prefix
123         writeIpv6Address(IpConversionUtil.extractIpv6Address(prefix), outBuffer);
124
125         // If prefix had mask, also write prefix
126         Optional.ofNullable(IpConversionUtil.hasIpv6Prefix(prefix)).ifPresent(mask ->
127                 writeMask(IpConversionUtil.convertIpv6PrefixToByteArray(mask), outBuffer,
128                         EncodeConstants.SIZE_OF_IPV6_ADDRESS_IN_BYTES));
129     }
130
131     /**
132      * Has mask getter.
133      *
134      * @param match Openflow match
135      * @return if field has or has not mask
136      */
137     protected abstract boolean getHasMask(Match match);
138
139     /**
140      * Oxm field numeric representation.
141      *
142      * @return numeric representation of oxm_field
143      */
144     protected abstract int getOxmFieldCode();
145
146     /**
147      * Oxm class code.
148      *
149      * @return numeric representation of oxm_class
150      */
151     protected abstract int getOxmClassCode();
152
153     /**
154      * Get value length.
155      *
156      * @return match entry value length (without mask length)
157      */
158     protected abstract int getValueLength();
159 }