blob: 30f6ad837490777f86d7dbd746bdee76635be3f7 [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 Li55ddcdb2016-11-21 17:04:01 +090022import org.onosproject.lisp.msg.types.LispAppDataLcafAddress.AppDataLcafAddressReader;
23import org.onosproject.lisp.msg.types.LispAppDataLcafAddress.AppDataLcafAddressWriter;
24import org.onosproject.lisp.msg.types.LispListLcafAddress.ListLcafAddressReader;
25import org.onosproject.lisp.msg.types.LispListLcafAddress.ListLcafAddressWriter;
26import org.onosproject.lisp.msg.types.LispNatLcafAddress.NatLcafAddressReader;
27import org.onosproject.lisp.msg.types.LispNatLcafAddress.NatLcafAddressWriter;
28import org.onosproject.lisp.msg.types.LispSegmentLcafAddress.SegmentLcafAddressReader;
29import org.onosproject.lisp.msg.types.LispSegmentLcafAddress.SegmentLcafAddressWriter;
30import org.onosproject.lisp.msg.types.LispSourceDestLcafAddress.SourceDestLcafAddressReader;
31import org.onosproject.lisp.msg.types.LispSourceDestLcafAddress.SourceDestLcafAddressWriter;
32import org.onosproject.lisp.msg.types.LispTeLcafAddress.TeLcafAddressReader;
33import org.onosproject.lisp.msg.types.LispTeLcafAddress.TeLcafAddressWriter;
Jian Lid4e63702016-08-30 18:29:20 +090034import org.slf4j.Logger;
35import org.slf4j.LoggerFactory;
Jian Lia7b394d2016-08-21 23:11:46 +090036
Jian Li09596002016-07-15 17:46:49 +090037import java.util.Objects;
38
39import static com.google.common.base.MoreObjects.toStringHelper;
Jian Li55ddcdb2016-11-21 17:04:01 +090040import static org.onosproject.lisp.msg.types.LispCanonicalAddressFormatEnum.APPLICATION_DATA;
41import static org.onosproject.lisp.msg.types.LispCanonicalAddressFormatEnum.LIST;
42import static org.onosproject.lisp.msg.types.LispCanonicalAddressFormatEnum.NAT;
43import static org.onosproject.lisp.msg.types.LispCanonicalAddressFormatEnum.SEGMENT;
44import static org.onosproject.lisp.msg.types.LispCanonicalAddressFormatEnum.SOURCE_DEST;
45import static org.onosproject.lisp.msg.types.LispCanonicalAddressFormatEnum.TRAFFIC_ENGINEERING;
46
Jian Li09596002016-07-15 17:46:49 +090047
48/**
49 * LISP Canonical Address Formatted address class.
Jian Lib9e1ac72016-11-07 21:15:17 +090050 * <p>
Jian Li8fc2d2f2016-08-08 14:43:53 +090051 * <pre>
52 * {@literal
Jian Lic7e20a52016-07-18 19:03:49 +090053 * 0 1 2 3
54 * 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
55 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
56 * | AFI = 16387 | Rsvd1 | Flags |
57 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
58 * | Type | Rsvd2 | Length |
59 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Jian Li8fc2d2f2016-08-08 14:43:53 +090060 * }</pre>
Jian Li09596002016-07-15 17:46:49 +090061 */
62public class LispLcafAddress extends LispAfiAddress {
63
Jian Lid4e63702016-08-30 18:29:20 +090064 private static final Logger log = LoggerFactory.getLogger(LispLcafAddress.class);
65
Jian Lia7b394d2016-08-21 23:11:46 +090066 private final LispCanonicalAddressFormatEnum lcafType;
67 private final byte reserved1;
68 private final byte reserved2;
69 private final byte flag;
70 private final short length;
Jian Li09596002016-07-15 17:46:49 +090071
Jian Lib9e1ac72016-11-07 21:15:17 +090072 private static final int LCAF_AFI_CODE_BYTE_LENGTH = 2;
73
Jian Lief0f7232016-11-15 19:55:46 +090074 private static final int LENGTH_FIELD_INDEX = 7;
75 public static final int COMMON_HEADER_SIZE = 8;
76
Jian Li09596002016-07-15 17:46:49 +090077 /**
78 * Initializes LCAF address.
79 *
Jian Lib9e1ac72016-11-07 21:15:17 +090080 * @param lcafType LCAF type
Jian Lic7e20a52016-07-18 19:03:49 +090081 * @param reserved1 reserved1 field
82 * @param reserved2 reserved2 field
Jian Lib9e1ac72016-11-07 21:15:17 +090083 * @param flag flag field
84 * @param length length field
Jian Li09596002016-07-15 17:46:49 +090085 */
Jian Lic7e20a52016-07-18 19:03:49 +090086 protected LispLcafAddress(LispCanonicalAddressFormatEnum lcafType,
Jian Lia7b394d2016-08-21 23:11:46 +090087 byte reserved1, byte reserved2, byte flag, short length) {
Jian Li09596002016-07-15 17:46:49 +090088 super(AddressFamilyIdentifierEnum.LCAF);
89 this.lcafType = lcafType;
Jian Lic7e20a52016-07-18 19:03:49 +090090 this.reserved1 = reserved1;
91 this.reserved2 = reserved2;
92 this.flag = flag;
93 this.length = length;
94 }
95
96 /**
97 * Initializes LCAF address.
98 *
Jian Lib9e1ac72016-11-07 21:15:17 +090099 * @param lcafType LCAF type
Jian Lic7e20a52016-07-18 19:03:49 +0900100 * @param reserved2 reserved2 field
Jian Lib9e1ac72016-11-07 21:15:17 +0900101 * @param flag flag field
102 * @param length length field
Jian Lic7e20a52016-07-18 19:03:49 +0900103 */
104 protected LispLcafAddress(LispCanonicalAddressFormatEnum lcafType,
Jian Lia7b394d2016-08-21 23:11:46 +0900105 byte reserved2, byte flag, short length) {
Jian Lic7e20a52016-07-18 19:03:49 +0900106 super(AddressFamilyIdentifierEnum.LCAF);
107 this.lcafType = lcafType;
108 this.reserved2 = reserved2;
109 this.flag = flag;
110 this.length = length;
111 this.reserved1 = 0;
112 }
113
114 /**
115 * Initializes LCAF address.
116 *
Jian Lib9e1ac72016-11-07 21:15:17 +0900117 * @param lcafType LCAF type
Jian Lic7e20a52016-07-18 19:03:49 +0900118 * @param reserved2 reserved2 field
Jian Lib9e1ac72016-11-07 21:15:17 +0900119 * @param length length field
Jian Lic7e20a52016-07-18 19:03:49 +0900120 */
121 protected LispLcafAddress(LispCanonicalAddressFormatEnum lcafType,
Jian Lia7b394d2016-08-21 23:11:46 +0900122 byte reserved2, short length) {
Jian Lic7e20a52016-07-18 19:03:49 +0900123 super(AddressFamilyIdentifierEnum.LCAF);
124 this.lcafType = lcafType;
125 this.reserved2 = reserved2;
126 this.length = length;
127 this.reserved1 = 0;
128 this.flag = 0;
129 }
130
131 /**
132 * Initializes LCAF address.
133 *
Jian Lib9e1ac72016-11-07 21:15:17 +0900134 * @param lcafType LCAF type
Jian Lic7e20a52016-07-18 19:03:49 +0900135 * @param reserved2 reserved2 field
136 */
137 protected LispLcafAddress(LispCanonicalAddressFormatEnum lcafType, byte reserved2) {
138 super(AddressFamilyIdentifierEnum.LCAF);
139 this.lcafType = lcafType;
140 this.reserved2 = reserved2;
141 this.reserved1 = 0;
142 this.flag = 0;
143 this.length = 0;
144 }
145
146 /**
147 * Initializes LCAF address.
148 *
149 * @param lcafType LCAF type
Jian Lib9e1ac72016-11-07 21:15:17 +0900150 * @param length length field
Jian Lia7b394d2016-08-21 23:11:46 +0900151 */
152 protected LispLcafAddress(LispCanonicalAddressFormatEnum lcafType, short length) {
153 super(AddressFamilyIdentifierEnum.LCAF);
154 this.lcafType = lcafType;
155 this.reserved1 = 0;
156 this.reserved2 = 0;
157 this.flag = 0;
158 this.length = length;
159 }
160
161 /**
162 * Initializes LCAF address.
163 *
164 * @param lcafType LCAF type
Jian Lic7e20a52016-07-18 19:03:49 +0900165 */
166 protected LispLcafAddress(LispCanonicalAddressFormatEnum lcafType) {
167 super(AddressFamilyIdentifierEnum.LCAF);
168 this.lcafType = lcafType;
169 this.reserved1 = 0;
170 this.reserved2 = 0;
171 this.flag = 0;
172 this.length = 0;
Jian Li09596002016-07-15 17:46:49 +0900173 }
174
175 /**
176 * Obtains LCAF type.
177 *
178 * @return LCAF type
179 */
180 public LispCanonicalAddressFormatEnum getType() {
181 return lcafType;
182 }
183
184 /**
Jian Lic7e20a52016-07-18 19:03:49 +0900185 * Obtains LCAF reserved1 value.
Jian Li09596002016-07-15 17:46:49 +0900186 *
Jian Lic7e20a52016-07-18 19:03:49 +0900187 * @return LCAF reserved1 value
Jian Li09596002016-07-15 17:46:49 +0900188 */
Jian Lic7e20a52016-07-18 19:03:49 +0900189 public byte getReserved1() {
190 return reserved1;
191 }
192
193 /**
194 * Obtains LCAF reserved2 value.
195 *
196 * @return LCAF reserved2 value
197 */
198 public byte getReserved2() {
199 return reserved2;
200 }
201
202 /**
203 * Obtains LCAF flag value.
204 *
205 * @return LCAF flag value
206 */
207 public byte getFlag() {
208 return flag;
209 }
210
211 /**
212 * Obtains LCAF length value.
213 *
214 * @return LCAF length value
215 */
Jian Lia7b394d2016-08-21 23:11:46 +0900216 public short getLength() {
Jian Lic7e20a52016-07-18 19:03:49 +0900217 return length;
Jian Li09596002016-07-15 17:46:49 +0900218 }
219
Jian Lia7b394d2016-08-21 23:11:46 +0900220 /**
221 * Deserializes common fields from byte buffer.
222 *
223 * @param byteBuf byte buffer
224 * @return LispLcafAddress with filled common data fields
225 */
226 public static LispLcafAddress deserializeCommon(ByteBuf byteBuf) {
227
Jian Lib9e1ac72016-11-07 21:15:17 +0900228 // let's skip first and second two bytes
,
229 // because it represents LCAF AFI code
230 byteBuf.skipBytes(LCAF_AFI_CODE_BYTE_LENGTH);
231
Jian Lia7b394d2016-08-21 23:11:46 +0900232 // reserved1 -> 8 bits
233 byte reserved1 = (byte) byteBuf.readUnsignedByte();
234
235 // flags -> 8 bits
236 byte flag = (byte) byteBuf.readUnsignedByte();
237
238 // LCAF type -> 8 bits
239 byte lcafType = (byte) byteBuf.readUnsignedByte();
240
241 // reserved2 -> 8bits
242 byte reserved2 = (byte) byteBuf.readUnsignedByte();
243
244 // length -> 16 bits
245 short length = (short) byteBuf.readUnsignedShort();
246
247 return new LispLcafAddress(LispCanonicalAddressFormatEnum.valueOf(lcafType),
Jian Lib9e1ac72016-11-07 21:15:17 +0900248 reserved1, reserved2, flag, length);
Jian Lia7b394d2016-08-21 23:11:46 +0900249 }
250
GUNiba871702016-08-22 21:06:02 +0900251 /**
Jian Lief0f7232016-11-15 19:55:46 +0900252 * Updates the header length field value based on the size of LISP header.
253 *
254 * @param lcafIndex the index of LCAF address, because LCAF address is
255 * contained inside LISP control message, so to correctly
256 * find the right LCAF length index, we need to know the
257 * absolute lcaf index inside LISP control message byte buf
258 * @param byteBuf netty byte buffer
259 */
260 public static void updateLength(int lcafIndex, ByteBuf byteBuf) {
yoonseon980cd7c2016-11-18 14:18:46 -0800261 byteBuf.setByte(lcafIndex + LENGTH_FIELD_INDEX,
262 byteBuf.writerIndex() - COMMON_HEADER_SIZE - lcafIndex);
Jian Lief0f7232016-11-15 19:55:46 +0900263 }
264
265 /**
GUNiba871702016-08-22 21:06:02 +0900266 * Serializes common fields to byte buffer.
267 *
268 * @param byteBuf byte buffer
269 * @param address LISP LCAF address instance
270 */
271 public static void serializeCommon(ByteBuf byteBuf, LispLcafAddress address) {
Jian Lief0f7232016-11-15 19:55:46 +0900272
Jian Lib9e1ac72016-11-07 21:15:17 +0900273 byteBuf.writeShort(AddressFamilyIdentifierEnum.LCAF.getIanaCode());
GUNiba871702016-08-22 21:06:02 +0900274 byteBuf.writeByte(address.getReserved1());
275 byteBuf.writeByte(address.getFlag());
276 byteBuf.writeByte(address.getType().getLispCode());
277 byteBuf.writeByte(address.getReserved2());
278 byteBuf.writeShort(address.getLength());
279 }
280
Jian Li09596002016-07-15 17:46:49 +0900281 @Override
282 public int hashCode() {
Jian Lid56f97e2016-07-19 15:48:15 +0900283 return Objects.hash(lcafType, reserved1, reserved2, flag, length);
Jian Li09596002016-07-15 17:46:49 +0900284 }
285
286 @Override
287 public boolean equals(Object obj) {
288 if (this == obj) {
289 return true;
290 }
291
292 if (obj instanceof LispLcafAddress) {
293 final LispLcafAddress other = (LispLcafAddress) obj;
294 return Objects.equals(this.lcafType, other.lcafType) &&
Jian Lib9e1ac72016-11-07 21:15:17 +0900295 Objects.equals(this.reserved1, other.reserved1) &&
296 Objects.equals(this.reserved2, other.reserved2) &&
297 Objects.equals(this.flag, other.flag) &&
298 Objects.equals(this.length, other.length);
Jian Li09596002016-07-15 17:46:49 +0900299 }
300 return false;
301 }
302
303 @Override
304 public String toString() {
305 return toStringHelper(this)
306 .add("lcafType", lcafType)
Jian Lic7e20a52016-07-18 19:03:49 +0900307 .add("reserved1", reserved1)
308 .add("reserved2", reserved2)
309 .add("flag", flag)
310 .add("length", length)
Jian Li09596002016-07-15 17:46:49 +0900311 .toString();
312 }
Jian Lia7b394d2016-08-21 23:11:46 +0900313
314 protected static class LcafAddressBuilder<T> {
315
316 protected byte reserved1;
317 protected byte flag;
318 protected byte lcafType;
319 protected byte reserved2;
320 protected short length;
321
322 /**
323 * Sets reserved1 value.
324 *
325 * @param reserved1 reserved1 value
326 * @return LcafAddressBuilder object
327 */
328 public T withReserved1(byte reserved1) {
329 this.reserved1 = reserved1;
330 return (T) this;
331 }
332
333 /**
334 * Sets flag.
335 *
336 * @param flag flag boolean
337 * @return LcafAddressBuilder object
338 */
339 public T withFlag(byte flag) {
340 this.flag = flag;
341 return (T) this;
342 }
343
344 /**
345 * Sets LCAF type.
346 *
347 * @param lcafType LCAF type
348 * @return LcafAddressBuilder object
349 */
350 public T withLcafType(byte lcafType) {
351 this.lcafType = lcafType;
352 return (T) this;
353 }
354
355 /**
356 * Sets reserved2 value.
357 *
358 * @param reserved2 reserved2 value
359 * @return LcafAddressBuilder object
360 */
361 public T withReserved2(byte reserved2) {
362 this.reserved2 = reserved2;
363 return (T) this;
364 }
365
366 /**
367 * Sets length value.
368 *
369 * @param length length value
370 * @return LcafAddressBuilder object
371 */
372 public T withLength(short length) {
373 this.length = length;
374 return (T) this;
375 }
376
377 /**
378 * Builds LispLcafAddress object.
379 *
380 * @return LispLcafAddress instance
381 */
382 public LispLcafAddress build() {
yoonseon980cd7c2016-11-18 14:18:46 -0800383 return new LispLcafAddress(LispCanonicalAddressFormatEnum
384 .valueOf(lcafType),
385 reserved1, reserved2, flag, length);
Jian Lia7b394d2016-08-21 23:11:46 +0900386 }
387 }
388
GUNiba871702016-08-22 21:06:02 +0900389 /**
390 * LISP LCAF reader class.
391 */
yoonseon980cd7c2016-11-18 14:18:46 -0800392 public static class LcafAddressReader
393 implements LispAddressReader<LispLcafAddress> {
Jian Lia7b394d2016-08-21 23:11:46 +0900394
395 private static final int LCAF_TYPE_FIELD_INDEX = 4;
396
397 @Override
yoonseon980cd7c2016-11-18 14:18:46 -0800398 public LispLcafAddress readFrom(ByteBuf byteBuf)
399 throws LispParseError, LispReaderException {
Jian Lia7b394d2016-08-21 23:11:46 +0900400
401 int index = byteBuf.readerIndex();
402
403 // LCAF type -> 8 bits
Jian Li55ddcdb2016-11-21 17:04:01 +0900404 byte lcafType = (byte) byteBuf.getUnsignedByte(index + LCAF_TYPE_FIELD_INDEX);
Jian Lia7b394d2016-08-21 23:11:46 +0900405
406 if (lcafType == APPLICATION_DATA.getLispCode()) {
Jian Li55ddcdb2016-11-21 17:04:01 +0900407 return new AppDataLcafAddressReader().readFrom(byteBuf);
408 }
409
410 if (lcafType == NAT.getLispCode()) {
411 return new NatLcafAddressReader().readFrom(byteBuf);
Jian Lia7b394d2016-08-21 23:11:46 +0900412 }
413
414 if (lcafType == LIST.getLispCode()) {
Jian Li55ddcdb2016-11-21 17:04:01 +0900415 return new ListLcafAddressReader().readFrom(byteBuf);
Jian Lia7b394d2016-08-21 23:11:46 +0900416 }
417
418 if (lcafType == SEGMENT.getLispCode()) {
Jian Li55ddcdb2016-11-21 17:04:01 +0900419 return new SegmentLcafAddressReader().readFrom(byteBuf);
Jian Lia7b394d2016-08-21 23:11:46 +0900420 }
421
422 if (lcafType == SOURCE_DEST.getLispCode()) {
Jian Li55ddcdb2016-11-21 17:04:01 +0900423 return new SourceDestLcafAddressReader().readFrom(byteBuf);
Jian Lia7b394d2016-08-21 23:11:46 +0900424 }
425
Jian Li99f83ef2016-11-03 19:14:25 +0100426 if (lcafType == TRAFFIC_ENGINEERING.getLispCode()) {
Jian Li55ddcdb2016-11-21 17:04:01 +0900427 return new TeLcafAddressReader().readFrom(byteBuf);
Jian Li99f83ef2016-11-03 19:14:25 +0100428 }
429
Jian Lid4e63702016-08-30 18:29:20 +0900430 log.warn("Unsupported LCAF type, please specify a correct LCAF type");
431
Jian Lia7b394d2016-08-21 23:11:46 +0900432 return null;
433 }
434 }
GUNiba871702016-08-22 21:06:02 +0900435
436 /**
437 * LISP LCAF address writer class.
438 */
yoonseon980cd7c2016-11-18 14:18:46 -0800439 public static class LcafAddressWriter
440 implements LispAddressWriter<LispLcafAddress> {
GUNiba871702016-08-22 21:06:02 +0900441
442 @Override
yoonseon980cd7c2016-11-18 14:18:46 -0800443 public void writeTo(ByteBuf byteBuf, LispLcafAddress address)
444 throws LispWriterException {
GUNiba871702016-08-22 21:06:02 +0900445 switch (address.getType()) {
446 case APPLICATION_DATA:
Jian Li55ddcdb2016-11-21 17:04:01 +0900447 new AppDataLcafAddressWriter().writeTo(byteBuf,
448 (LispAppDataLcafAddress) address);
449 break;
450 case NAT:
451 new NatLcafAddressWriter().writeTo(byteBuf,
452 (LispNatLcafAddress) address);
GUNiba871702016-08-22 21:06:02 +0900453 break;
454 case LIST:
Jian Li55ddcdb2016-11-21 17:04:01 +0900455 new ListLcafAddressWriter().writeTo(byteBuf,
GUNiba871702016-08-22 21:06:02 +0900456 (LispListLcafAddress) address);
457 break;
458 case SEGMENT:
Jian Li55ddcdb2016-11-21 17:04:01 +0900459 new SegmentLcafAddressWriter().writeTo(byteBuf,
460 (LispSegmentLcafAddress) address);
GUNiba871702016-08-22 21:06:02 +0900461 break;
462 case SOURCE_DEST:
Jian Li55ddcdb2016-11-21 17:04:01 +0900463 new SourceDestLcafAddressWriter().writeTo(byteBuf,
464 (LispSourceDestLcafAddress) address);
GUNiba871702016-08-22 21:06:02 +0900465 break;
Jian Li99f83ef2016-11-03 19:14:25 +0100466 case TRAFFIC_ENGINEERING:
Jian Li55ddcdb2016-11-21 17:04:01 +0900467 new TeLcafAddressWriter().writeTo(byteBuf,
Jian Li99f83ef2016-11-03 19:14:25 +0100468 (LispTeLcafAddress) address);
469 break;
Jian Lid4e63702016-08-30 18:29:20 +0900470 default:
471 log.warn("Unsupported LCAF type, please specify a correct LCAF type");
472 break;
GUNiba871702016-08-22 21:06:02 +0900473 }
474 }
475 }
Jian Li09596002016-07-15 17:46:49 +0900476}