blob: 073ca5a35e35f223101d0e89614e91b59c3aaa87 [file] [log] [blame]
Jian Li09596002016-07-15 17:46:49 +09001/*
2 * Copyright 2016-present Open Networking Laboratory
3 *
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 */
16package org.onosproject.lisp.msg.types;
17
Jian Lia7b394d2016-08-21 23:11:46 +090018import io.netty.buffer.ByteBuf;
19import org.onosproject.lisp.msg.exceptions.LispParseError;
20import org.onosproject.lisp.msg.exceptions.LispReaderException;
GUNiba871702016-08-22 21:06:02 +090021import org.onosproject.lisp.msg.exceptions.LispWriterException;
Jian Lid4e63702016-08-30 18:29:20 +090022import org.slf4j.Logger;
23import org.slf4j.LoggerFactory;
Jian Lia7b394d2016-08-21 23:11:46 +090024
Jian Li09596002016-07-15 17:46:49 +090025import java.util.Objects;
26
27import static com.google.common.base.MoreObjects.toStringHelper;
Jian Lia7b394d2016-08-21 23:11:46 +090028import static org.onosproject.lisp.msg.types.LispCanonicalAddressFormatEnum.*;
Jian Li09596002016-07-15 17:46:49 +090029
30/**
31 * LISP Canonical Address Formatted address class.
Jian Lib9e1ac72016-11-07 21:15:17 +090032 * <p>
Jian Li8fc2d2f2016-08-08 14:43:53 +090033 * <pre>
34 * {@literal
Jian Lic7e20a52016-07-18 19:03:49 +090035 * 0 1 2 3
36 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
37 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
38 * | AFI = 16387 | Rsvd1 | Flags |
39 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
40 * | Type | Rsvd2 | Length |
41 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Jian Li8fc2d2f2016-08-08 14:43:53 +090042 * }</pre>
Jian Li09596002016-07-15 17:46:49 +090043 */
44public class LispLcafAddress extends LispAfiAddress {
45
Jian Lid4e63702016-08-30 18:29:20 +090046 private static final Logger log = LoggerFactory.getLogger(LispLcafAddress.class);
47
Jian Lia7b394d2016-08-21 23:11:46 +090048 private final LispCanonicalAddressFormatEnum lcafType;
49 private final byte reserved1;
50 private final byte reserved2;
51 private final byte flag;
52 private final short length;
Jian Li09596002016-07-15 17:46:49 +090053
Jian Lib9e1ac72016-11-07 21:15:17 +090054 private static final int LCAF_AFI_CODE_BYTE_LENGTH = 2;
55
Jian Li09596002016-07-15 17:46:49 +090056 /**
57 * Initializes LCAF address.
58 *
Jian Lib9e1ac72016-11-07 21:15:17 +090059 * @param lcafType LCAF type
Jian Lic7e20a52016-07-18 19:03:49 +090060 * @param reserved1 reserved1 field
61 * @param reserved2 reserved2 field
Jian Lib9e1ac72016-11-07 21:15:17 +090062 * @param flag flag field
63 * @param length length field
Jian Li09596002016-07-15 17:46:49 +090064 */
Jian Lic7e20a52016-07-18 19:03:49 +090065 protected LispLcafAddress(LispCanonicalAddressFormatEnum lcafType,
Jian Lia7b394d2016-08-21 23:11:46 +090066 byte reserved1, byte reserved2, byte flag, short length) {
Jian Li09596002016-07-15 17:46:49 +090067 super(AddressFamilyIdentifierEnum.LCAF);
68 this.lcafType = lcafType;
Jian Lic7e20a52016-07-18 19:03:49 +090069 this.reserved1 = reserved1;
70 this.reserved2 = reserved2;
71 this.flag = flag;
72 this.length = length;
73 }
74
75 /**
76 * Initializes LCAF address.
77 *
Jian Lib9e1ac72016-11-07 21:15:17 +090078 * @param lcafType LCAF type
Jian Lic7e20a52016-07-18 19:03:49 +090079 * @param reserved2 reserved2 field
Jian Lib9e1ac72016-11-07 21:15:17 +090080 * @param flag flag field
81 * @param length length field
Jian Lic7e20a52016-07-18 19:03:49 +090082 */
83 protected LispLcafAddress(LispCanonicalAddressFormatEnum lcafType,
Jian Lia7b394d2016-08-21 23:11:46 +090084 byte reserved2, byte flag, short length) {
Jian Lic7e20a52016-07-18 19:03:49 +090085 super(AddressFamilyIdentifierEnum.LCAF);
86 this.lcafType = lcafType;
87 this.reserved2 = reserved2;
88 this.flag = flag;
89 this.length = length;
90 this.reserved1 = 0;
91 }
92
93 /**
94 * Initializes LCAF address.
95 *
Jian Lib9e1ac72016-11-07 21:15:17 +090096 * @param lcafType LCAF type
Jian Lic7e20a52016-07-18 19:03:49 +090097 * @param reserved2 reserved2 field
Jian Lib9e1ac72016-11-07 21:15:17 +090098 * @param length length field
Jian Lic7e20a52016-07-18 19:03:49 +090099 */
100 protected LispLcafAddress(LispCanonicalAddressFormatEnum lcafType,
Jian Lia7b394d2016-08-21 23:11:46 +0900101 byte reserved2, short length) {
Jian Lic7e20a52016-07-18 19:03:49 +0900102 super(AddressFamilyIdentifierEnum.LCAF);
103 this.lcafType = lcafType;
104 this.reserved2 = reserved2;
105 this.length = length;
106 this.reserved1 = 0;
107 this.flag = 0;
108 }
109
110 /**
111 * Initializes LCAF address.
112 *
Jian Lib9e1ac72016-11-07 21:15:17 +0900113 * @param lcafType LCAF type
Jian Lic7e20a52016-07-18 19:03:49 +0900114 * @param reserved2 reserved2 field
115 */
116 protected LispLcafAddress(LispCanonicalAddressFormatEnum lcafType, byte reserved2) {
117 super(AddressFamilyIdentifierEnum.LCAF);
118 this.lcafType = lcafType;
119 this.reserved2 = reserved2;
120 this.reserved1 = 0;
121 this.flag = 0;
122 this.length = 0;
123 }
124
125 /**
126 * Initializes LCAF address.
127 *
128 * @param lcafType LCAF type
Jian Lib9e1ac72016-11-07 21:15:17 +0900129 * @param length length field
Jian Lia7b394d2016-08-21 23:11:46 +0900130 */
131 protected LispLcafAddress(LispCanonicalAddressFormatEnum lcafType, short length) {
132 super(AddressFamilyIdentifierEnum.LCAF);
133 this.lcafType = lcafType;
134 this.reserved1 = 0;
135 this.reserved2 = 0;
136 this.flag = 0;
137 this.length = length;
138 }
139
140 /**
141 * Initializes LCAF address.
142 *
143 * @param lcafType LCAF type
Jian Lic7e20a52016-07-18 19:03:49 +0900144 */
145 protected LispLcafAddress(LispCanonicalAddressFormatEnum lcafType) {
146 super(AddressFamilyIdentifierEnum.LCAF);
147 this.lcafType = lcafType;
148 this.reserved1 = 0;
149 this.reserved2 = 0;
150 this.flag = 0;
151 this.length = 0;
Jian Li09596002016-07-15 17:46:49 +0900152 }
153
154 /**
155 * Obtains LCAF type.
156 *
157 * @return LCAF type
158 */
159 public LispCanonicalAddressFormatEnum getType() {
160 return lcafType;
161 }
162
163 /**
Jian Lic7e20a52016-07-18 19:03:49 +0900164 * Obtains LCAF reserved1 value.
Jian Li09596002016-07-15 17:46:49 +0900165 *
Jian Lic7e20a52016-07-18 19:03:49 +0900166 * @return LCAF reserved1 value
Jian Li09596002016-07-15 17:46:49 +0900167 */
Jian Lic7e20a52016-07-18 19:03:49 +0900168 public byte getReserved1() {
169 return reserved1;
170 }
171
172 /**
173 * Obtains LCAF reserved2 value.
174 *
175 * @return LCAF reserved2 value
176 */
177 public byte getReserved2() {
178 return reserved2;
179 }
180
181 /**
182 * Obtains LCAF flag value.
183 *
184 * @return LCAF flag value
185 */
186 public byte getFlag() {
187 return flag;
188 }
189
190 /**
191 * Obtains LCAF length value.
192 *
193 * @return LCAF length value
194 */
Jian Lia7b394d2016-08-21 23:11:46 +0900195 public short getLength() {
Jian Lic7e20a52016-07-18 19:03:49 +0900196 return length;
Jian Li09596002016-07-15 17:46:49 +0900197 }
198
Jian Lia7b394d2016-08-21 23:11:46 +0900199 /**
200 * Deserializes common fields from byte buffer.
201 *
202 * @param byteBuf byte buffer
203 * @return LispLcafAddress with filled common data fields
204 */
205 public static LispLcafAddress deserializeCommon(ByteBuf byteBuf) {
206
Jian Lib9e1ac72016-11-07 21:15:17 +0900207 // let's skip first and second two bytes
,
208 // because it represents LCAF AFI code
209 byteBuf.skipBytes(LCAF_AFI_CODE_BYTE_LENGTH);
210
Jian Lia7b394d2016-08-21 23:11:46 +0900211 // reserved1 -> 8 bits
212 byte reserved1 = (byte) byteBuf.readUnsignedByte();
213
214 // flags -> 8 bits
215 byte flag = (byte) byteBuf.readUnsignedByte();
216
217 // LCAF type -> 8 bits
218 byte lcafType = (byte) byteBuf.readUnsignedByte();
219
220 // reserved2 -> 8bits
221 byte reserved2 = (byte) byteBuf.readUnsignedByte();
222
223 // length -> 16 bits
224 short length = (short) byteBuf.readUnsignedShort();
225
226 return new LispLcafAddress(LispCanonicalAddressFormatEnum.valueOf(lcafType),
Jian Lib9e1ac72016-11-07 21:15:17 +0900227 reserved1, reserved2, flag, length);
Jian Lia7b394d2016-08-21 23:11:46 +0900228 }
229
GUNiba871702016-08-22 21:06:02 +0900230 /**
231 * Serializes common fields to byte buffer.
232 *
233 * @param byteBuf byte buffer
234 * @param address LISP LCAF address instance
235 */
236 public static void serializeCommon(ByteBuf byteBuf, LispLcafAddress address) {
Jian Lib9e1ac72016-11-07 21:15:17 +0900237 byteBuf.writeShort(AddressFamilyIdentifierEnum.LCAF.getIanaCode());
GUNiba871702016-08-22 21:06:02 +0900238 byteBuf.writeByte(address.getReserved1());
239 byteBuf.writeByte(address.getFlag());
240 byteBuf.writeByte(address.getType().getLispCode());
241 byteBuf.writeByte(address.getReserved2());
242 byteBuf.writeShort(address.getLength());
243 }
244
Jian Li09596002016-07-15 17:46:49 +0900245 @Override
246 public int hashCode() {
Jian Lid56f97e2016-07-19 15:48:15 +0900247 return Objects.hash(lcafType, reserved1, reserved2, flag, length);
Jian Li09596002016-07-15 17:46:49 +0900248 }
249
250 @Override
251 public boolean equals(Object obj) {
252 if (this == obj) {
253 return true;
254 }
255
256 if (obj instanceof LispLcafAddress) {
257 final LispLcafAddress other = (LispLcafAddress) obj;
258 return Objects.equals(this.lcafType, other.lcafType) &&
Jian Lib9e1ac72016-11-07 21:15:17 +0900259 Objects.equals(this.reserved1, other.reserved1) &&
260 Objects.equals(this.reserved2, other.reserved2) &&
261 Objects.equals(this.flag, other.flag) &&
262 Objects.equals(this.length, other.length);
Jian Li09596002016-07-15 17:46:49 +0900263 }
264 return false;
265 }
266
267 @Override
268 public String toString() {
269 return toStringHelper(this)
270 .add("lcafType", lcafType)
Jian Lic7e20a52016-07-18 19:03:49 +0900271 .add("reserved1", reserved1)
272 .add("reserved2", reserved2)
273 .add("flag", flag)
274 .add("length", length)
Jian Li09596002016-07-15 17:46:49 +0900275 .toString();
276 }
Jian Lia7b394d2016-08-21 23:11:46 +0900277
278 protected static class LcafAddressBuilder<T> {
279
280 protected byte reserved1;
281 protected byte flag;
282 protected byte lcafType;
283 protected byte reserved2;
284 protected short length;
285
286 /**
287 * Sets reserved1 value.
288 *
289 * @param reserved1 reserved1 value
290 * @return LcafAddressBuilder object
291 */
292 public T withReserved1(byte reserved1) {
293 this.reserved1 = reserved1;
294 return (T) this;
295 }
296
297 /**
298 * Sets flag.
299 *
300 * @param flag flag boolean
301 * @return LcafAddressBuilder object
302 */
303 public T withFlag(byte flag) {
304 this.flag = flag;
305 return (T) this;
306 }
307
308 /**
309 * Sets LCAF type.
310 *
311 * @param lcafType LCAF type
312 * @return LcafAddressBuilder object
313 */
314 public T withLcafType(byte lcafType) {
315 this.lcafType = lcafType;
316 return (T) this;
317 }
318
319 /**
320 * Sets reserved2 value.
321 *
322 * @param reserved2 reserved2 value
323 * @return LcafAddressBuilder object
324 */
325 public T withReserved2(byte reserved2) {
326 this.reserved2 = reserved2;
327 return (T) this;
328 }
329
330 /**
331 * Sets length value.
332 *
333 * @param length length value
334 * @return LcafAddressBuilder object
335 */
336 public T withLength(short length) {
337 this.length = length;
338 return (T) this;
339 }
340
341 /**
342 * Builds LispLcafAddress object.
343 *
344 * @return LispLcafAddress instance
345 */
346 public LispLcafAddress build() {
347 return new LispLcafAddress(LispCanonicalAddressFormatEnum.valueOf(lcafType),
Jian Lib9e1ac72016-11-07 21:15:17 +0900348 reserved1, reserved2, flag, length);
Jian Lia7b394d2016-08-21 23:11:46 +0900349 }
350 }
351
GUNiba871702016-08-22 21:06:02 +0900352 /**
353 * LISP LCAF reader class.
354 */
Jian Lia7b394d2016-08-21 23:11:46 +0900355 public static class LcafAddressReader implements LispAddressReader<LispLcafAddress> {
356
357 private static final int LCAF_TYPE_FIELD_INDEX = 4;
358
359 @Override
360 public LispLcafAddress readFrom(ByteBuf byteBuf) throws LispParseError, LispReaderException {
361
362 int index = byteBuf.readerIndex();
363
364 // LCAF type -> 8 bits
365 byte lcafType = (byte) byteBuf.getUnsignedByte(index + LCAF_TYPE_FIELD_INDEX);
366
367 if (lcafType == APPLICATION_DATA.getLispCode()) {
368 return new LispAppDataLcafAddress.AppDataLcafAddressReader().readFrom(byteBuf);
369 }
370
371 if (lcafType == LIST.getLispCode()) {
372 return new LispListLcafAddress.ListLcafAddressReader().readFrom(byteBuf);
373 }
374
375 if (lcafType == SEGMENT.getLispCode()) {
376 return new LispSegmentLcafAddress.SegmentLcafAddressReader().readFrom(byteBuf);
377 }
378
379 if (lcafType == SOURCE_DEST.getLispCode()) {
380 return new LispSourceDestLcafAddress.SourceDestLcafAddressReader().readFrom(byteBuf);
381 }
382
Jian Li99f83ef2016-11-03 19:14:25 +0100383 if (lcafType == TRAFFIC_ENGINEERING.getLispCode()) {
384 return new LispTeLcafAddress.TeAddressBuilder.TeLcafAddressReader().readFrom(byteBuf);
385 }
386
Jian Lid4e63702016-08-30 18:29:20 +0900387 log.warn("Unsupported LCAF type, please specify a correct LCAF type");
388
Jian Lia7b394d2016-08-21 23:11:46 +0900389 return null;
390 }
391 }
GUNiba871702016-08-22 21:06:02 +0900392
393 /**
394 * LISP LCAF address writer class.
395 */
396 public static class LcafAddressWriter implements LispAddressWriter<LispLcafAddress> {
397
398 @Override
399 public void writeTo(ByteBuf byteBuf, LispLcafAddress address) throws LispWriterException {
400 switch (address.getType()) {
401 case APPLICATION_DATA:
402 new LispAppDataLcafAddress.AppDataLcafAddressWriter().writeTo(byteBuf,
403 (LispAppDataLcafAddress) address);
404 break;
405 case LIST:
406 new LispListLcafAddress.ListLcafAddressWriter().writeTo(byteBuf,
407 (LispListLcafAddress) address);
408 break;
409 case SEGMENT:
410 new LispSegmentLcafAddress.SegmentLcafAddressWriter().writeTo(byteBuf,
411 (LispSegmentLcafAddress) address);
412 break;
413 case SOURCE_DEST:
414 new LispSourceDestLcafAddress.SourceDestLcafAddressWriter().writeTo(byteBuf,
415 (LispSourceDestLcafAddress) address);
416 break;
Jian Li99f83ef2016-11-03 19:14:25 +0100417 case TRAFFIC_ENGINEERING:
418 new LispTeLcafAddress.TeAddressBuilder.TeLcafAddressWriter().writeTo(byteBuf,
419 (LispTeLcafAddress) address);
420 break;
Jian Lid4e63702016-08-30 18:29:20 +0900421 default:
422 log.warn("Unsupported LCAF type, please specify a correct LCAF type");
423 break;
GUNiba871702016-08-22 21:06:02 +0900424 }
425 }
426 }
Jian Li09596002016-07-15 17:46:49 +0900427}