blob: abaaa88b8c1f3890c9e8d946ffc2b6301e676b04 [file] [log] [blame]
Jonathan Hart3930f632015-10-19 12:12:51 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2017-present Open Networking Foundation
Jonathan Hart3930f632015-10-19 12:12:51 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.onosproject.routing.fpm.protocol;
18
19import com.google.common.base.MoreObjects;
Jonathan Hart72bbf882017-04-14 08:42:51 -070020import com.google.common.collect.ImmutableSet;
Jonathan Hart3930f632015-10-19 12:12:51 -070021import org.onlab.packet.DeserializationException;
22
Kalhee Kimba366062017-11-07 16:32:09 +000023import org.jboss.netty.buffer.ChannelBuffer;
24import org.jboss.netty.buffer.ChannelBuffers;
Jonathan Hart3930f632015-10-19 12:12:51 -070025import java.nio.ByteBuffer;
26
27import static org.onlab.packet.PacketUtils.checkInput;
28
29/**
30 * FPM header.
31 */
32public final class FpmHeader {
33 public static final int FPM_HEADER_LENGTH = 4;
Kalhee Kimba366062017-11-07 16:32:09 +000034 public static final int FPM_MESSAGE_MAX_LENGTH = 4096;
Jonathan Hart3930f632015-10-19 12:12:51 -070035
36 public static final short FPM_VERSION_1 = 1;
Jonathan Hart72bbf882017-04-14 08:42:51 -070037 public static final short FPM_VERSION_ONOS_EXT = 32;
38
39 private static final ImmutableSet<Short> SUPPORTED_VERSIONS =
40 ImmutableSet.<Short>builder()
41 .add(FPM_VERSION_1)
42 .add(FPM_VERSION_ONOS_EXT)
43 .build();
44
Jonathan Hart3930f632015-10-19 12:12:51 -070045 public static final short FPM_TYPE_NETLINK = 1;
Jonathan Hart72bbf882017-04-14 08:42:51 -070046 public static final short FPM_TYPE_PROTOBUF = 2;
47 public static final short FPM_TYPE_KEEPALIVE = 32;
Jonathan Hart3930f632015-10-19 12:12:51 -070048
49 private static final String VERSION_NOT_SUPPORTED = "FPM version not supported: ";
50 private static final String TYPE_NOT_SUPPORTED = "FPM type not supported: ";
51
52 private final short version;
53 private final short type;
54 private final int length;
55
56 private final Netlink netlink;
57
58 /**
59 * Class constructor.
60 *
61 * @param version version
62 * @param type type
63 * @param length length
64 * @param netlink netlink header
65 */
Kalhee Kim715dd732018-01-23 14:39:56 +000066 private FpmHeader(short version, short type, int length, Netlink netlink) {
Jonathan Hart3930f632015-10-19 12:12:51 -070067 this.version = version;
68 this.type = type;
69 this.length = length;
70 this.netlink = netlink;
71 }
72
73 /**
74 * Returns the protocol version.
75 *
76 * @return protocol version
77 */
78 public short version() {
79 return version;
80 }
81
82 /**
83 * Returns the type.
84 *
85 * @return type
86 */
87 public short type() {
88 return type;
89 }
90
91 /**
92 * Returns the message length.
93 *
94 * @return message length
95 */
96 public int length() {
97 return length;
98 }
99
100 /**
101 * Returns the netlink header.
102 *
103 * @return netlink header
104 */
105 public Netlink netlink() {
106 return netlink;
107 }
108
109 @Override
110 public String toString() {
111 return MoreObjects.toStringHelper(getClass())
112 .add("version", version)
113 .add("type", type)
114 .add("length", length)
115 .add("netlink", netlink)
116 .toString();
117 }
118
119 /**
120 * Decodes an FPM header from an input buffer.
121 *
122 * @param buffer input buffer
123 * @param start starting position the FPM header
124 * @param length length of the message
125 * @return FPM header
126 * @throws DeserializationException if an FPM header could not be decoded
127 * from the input buffer
128 */
129 public static FpmHeader decode(byte[] buffer, int start, int length) throws
130 DeserializationException {
131 checkInput(buffer, start, length, FPM_HEADER_LENGTH);
132
133 ByteBuffer bb = ByteBuffer.wrap(buffer, start, length);
134
135 short version = bb.get();
Jonathan Hart72bbf882017-04-14 08:42:51 -0700136 if (!SUPPORTED_VERSIONS.contains(version)) {
Jonathan Hart3930f632015-10-19 12:12:51 -0700137 throw new DeserializationException(VERSION_NOT_SUPPORTED + version);
138 }
139
140 short type = bb.get();
Jonathan Hart72bbf882017-04-14 08:42:51 -0700141 int messageLength = bb.getShort();
142
143 if (type == FPM_TYPE_KEEPALIVE) {
144 return new FpmHeader(version, type, messageLength, null);
145 }
146
Jonathan Hart3930f632015-10-19 12:12:51 -0700147 if (type != FPM_TYPE_NETLINK) {
148 throw new DeserializationException(TYPE_NOT_SUPPORTED + type);
149 }
150
Jonathan Hart3930f632015-10-19 12:12:51 -0700151 Netlink netlink = Netlink.decode(buffer, bb.position(), bb.limit() - bb.position());
152
153 return new FpmHeader(version, type, messageLength, netlink);
154 }
Kalhee Kimba366062017-11-07 16:32:09 +0000155
156 /**
157 * Encode the FpmHeader contents into a ChannelBuffer.
158 *
159 * @return filled in ChannelBuffer
160 */
161 public ChannelBuffer encode() {
162
163 ChannelBuffer cb = ChannelBuffers.buffer(FPM_MESSAGE_MAX_LENGTH);
164
165 cb.writeByte(version);
166 cb.writeByte(type);
167 cb.writeShort(length);
168
169 netlink.encode(cb);
170 return cb;
171 }
Kalhee Kim715dd732018-01-23 14:39:56 +0000172
173 /**
174 * Returns a new FpmHeader builder.
175 *
176 * @return FpmHeader builder
177 */
178 public static Builder builder() {
179 return new Builder();
180 }
181
182 /**
183 * FpmHeader Builder.
184 */
185 public static final class Builder {
186
187 private short version = FPM_VERSION_1;
188 private short type = FPM_TYPE_NETLINK;
189 private int length = 0;
190 private Netlink netlink = null;
191
192 /**
193 * Hide class constructor.
194 */
195 private Builder() {
196 }
197
198 /**
199 * Sets version for the FpmHeader that will be built.
200 *
201 * @param version to use for built FpmHeader
202 * @return this builder
203 */
204 public Builder version(short version) {
205 this.version = version;
206 return this;
207 }
208
209 /**
210 * Sets type for the FpmHeader that will be built.
211 *
212 * @param type to use for built FpmHeader
213 * @return this builder
214 */
215 public Builder type(short type) {
216 this.type = type;
217 return this;
218 }
219
220 /**
221 * Sets length for the FpmHeader that will be built.
222 *
223 * @param length to use for built FpmHeader
224 * @return this builder
225 */
226 public Builder length(int length) {
227 this.length = length;
228 return this;
229 }
230
231 /**
232 * Sets netlink for the FpmHeader that will be built.
233 *
234 * @param netlink to use for built FpmHeader
235 * @return this builder
236 */
237 public Builder netlink(Netlink netlink) {
238 this.netlink = netlink;
239 return this;
240 }
241
242 /**
243 * Builds the FpmHeader.
244 *
245 * @return FpmHeader reference
246 */
247 public FpmHeader build() {
248 return new FpmHeader(version, type, length, netlink);
249 }
250 }
Jonathan Hart3930f632015-10-19 12:12:51 -0700251}