blob: 5aff3b9200d8fb63f22fba92675e1b268a1f9de3 [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 */
Jian Lif31019a2017-02-05 07:57:46 +090016package org.onosproject.lisp.msg.types.lcaf;
Jian Li09596002016-07-15 17:46:49 +090017
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 Lif31019a2017-02-05 07:57:46 +090022import org.onosproject.lisp.msg.types.AddressFamilyIdentifierEnum;
23import org.onosproject.lisp.msg.types.LispAddressReader;
24import org.onosproject.lisp.msg.types.LispAddressWriter;
25import org.onosproject.lisp.msg.types.LispAfiAddress;
Jian Lid4e63702016-08-30 18:29:20 +090026import org.slf4j.Logger;
27import org.slf4j.LoggerFactory;
Jian Lia7b394d2016-08-21 23:11:46 +090028
Jian Li09596002016-07-15 17:46:49 +090029import java.util.Objects;
30
31import static com.google.common.base.MoreObjects.toStringHelper;
Jian Lif31019a2017-02-05 07:57:46 +090032import static org.onosproject.lisp.msg.types.lcaf.LispCanonicalAddressFormatEnum.APPLICATION_DATA;
33import static org.onosproject.lisp.msg.types.lcaf.LispCanonicalAddressFormatEnum.LIST;
Jian Li2af9eaa2017-02-05 09:15:07 +090034import static org.onosproject.lisp.msg.types.lcaf.LispCanonicalAddressFormatEnum.MULTICAST;
Jian Lif31019a2017-02-05 07:57:46 +090035import static org.onosproject.lisp.msg.types.lcaf.LispCanonicalAddressFormatEnum.NAT;
36import static org.onosproject.lisp.msg.types.lcaf.LispCanonicalAddressFormatEnum.SEGMENT;
37import static org.onosproject.lisp.msg.types.lcaf.LispCanonicalAddressFormatEnum.SOURCE_DEST;
38import static org.onosproject.lisp.msg.types.lcaf.LispCanonicalAddressFormatEnum.TRAFFIC_ENGINEERING;
Jian Li55ddcdb2016-11-21 17:04:01 +090039
Jian Li09596002016-07-15 17:46:49 +090040
41/**
42 * LISP Canonical Address Formatted address class.
Jian Lib9e1ac72016-11-07 21:15:17 +090043 * <p>
Jian Li8fc2d2f2016-08-08 14:43:53 +090044 * <pre>
45 * {@literal
Jian Lic7e20a52016-07-18 19:03:49 +090046 * 0 1 2 3
47 * 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
48 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
49 * | AFI = 16387 | Rsvd1 | Flags |
50 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
51 * | Type | Rsvd2 | Length |
52 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Jian Li8fc2d2f2016-08-08 14:43:53 +090053 * }</pre>
Jian Li09596002016-07-15 17:46:49 +090054 */
55public class LispLcafAddress extends LispAfiAddress {
56
Jian Lid4e63702016-08-30 18:29:20 +090057 private static final Logger log = LoggerFactory.getLogger(LispLcafAddress.class);
58
Jian Lia7b394d2016-08-21 23:11:46 +090059 private final LispCanonicalAddressFormatEnum lcafType;
60 private final byte reserved1;
61 private final byte reserved2;
62 private final byte flag;
63 private final short length;
Jian Li09596002016-07-15 17:46:49 +090064
Jian Lib9e1ac72016-11-07 21:15:17 +090065 private static final int LCAF_AFI_CODE_BYTE_LENGTH = 2;
66
Jian Lief0f7232016-11-15 19:55:46 +090067 private static final int LENGTH_FIELD_INDEX = 7;
68 public static final int COMMON_HEADER_SIZE = 8;
69
Jian Li09596002016-07-15 17:46:49 +090070 /**
71 * Initializes LCAF address.
72 *
Jian Lib9e1ac72016-11-07 21:15:17 +090073 * @param lcafType LCAF type
Jian Lic7e20a52016-07-18 19:03:49 +090074 * @param reserved1 reserved1 field
75 * @param reserved2 reserved2 field
Jian Lib9e1ac72016-11-07 21:15:17 +090076 * @param flag flag field
77 * @param length length field
Jian Li09596002016-07-15 17:46:49 +090078 */
Jian Lic7e20a52016-07-18 19:03:49 +090079 protected LispLcafAddress(LispCanonicalAddressFormatEnum lcafType,
Jian Lia7b394d2016-08-21 23:11:46 +090080 byte reserved1, byte reserved2, byte flag, short length) {
Jian Li09596002016-07-15 17:46:49 +090081 super(AddressFamilyIdentifierEnum.LCAF);
82 this.lcafType = lcafType;
Jian Lic7e20a52016-07-18 19:03:49 +090083 this.reserved1 = reserved1;
84 this.reserved2 = reserved2;
85 this.flag = flag;
86 this.length = length;
87 }
88
89 /**
90 * Initializes LCAF address.
91 *
Jian Lib9e1ac72016-11-07 21:15:17 +090092 * @param lcafType LCAF type
Jian Lic7e20a52016-07-18 19:03:49 +090093 * @param reserved2 reserved2 field
Jian Lib9e1ac72016-11-07 21:15:17 +090094 * @param flag flag field
95 * @param length length field
Jian Lic7e20a52016-07-18 19:03:49 +090096 */
97 protected LispLcafAddress(LispCanonicalAddressFormatEnum lcafType,
Jian Lia7b394d2016-08-21 23:11:46 +090098 byte reserved2, byte flag, short length) {
Jian Lic7e20a52016-07-18 19:03:49 +090099 super(AddressFamilyIdentifierEnum.LCAF);
100 this.lcafType = lcafType;
101 this.reserved2 = reserved2;
102 this.flag = flag;
103 this.length = length;
104 this.reserved1 = 0;
105 }
106
107 /**
108 * Initializes LCAF address.
109 *
Jian Lib9e1ac72016-11-07 21:15:17 +0900110 * @param lcafType LCAF type
Jian Lic7e20a52016-07-18 19:03:49 +0900111 * @param reserved2 reserved2 field
Jian Lib9e1ac72016-11-07 21:15:17 +0900112 * @param length length field
Jian Lic7e20a52016-07-18 19:03:49 +0900113 */
114 protected LispLcafAddress(LispCanonicalAddressFormatEnum lcafType,
Jian Lia7b394d2016-08-21 23:11:46 +0900115 byte reserved2, short length) {
Jian Lic7e20a52016-07-18 19:03:49 +0900116 super(AddressFamilyIdentifierEnum.LCAF);
117 this.lcafType = lcafType;
118 this.reserved2 = reserved2;
119 this.length = length;
120 this.reserved1 = 0;
121 this.flag = 0;
122 }
123
124 /**
125 * Initializes LCAF address.
126 *
Jian Lib9e1ac72016-11-07 21:15:17 +0900127 * @param lcafType LCAF type
Jian Lic7e20a52016-07-18 19:03:49 +0900128 * @param reserved2 reserved2 field
129 */
130 protected LispLcafAddress(LispCanonicalAddressFormatEnum lcafType, byte reserved2) {
131 super(AddressFamilyIdentifierEnum.LCAF);
132 this.lcafType = lcafType;
133 this.reserved2 = reserved2;
134 this.reserved1 = 0;
135 this.flag = 0;
136 this.length = 0;
137 }
138
139 /**
140 * Initializes LCAF address.
141 *
142 * @param lcafType LCAF type
Jian Lib9e1ac72016-11-07 21:15:17 +0900143 * @param length length field
Jian Lia7b394d2016-08-21 23:11:46 +0900144 */
145 protected LispLcafAddress(LispCanonicalAddressFormatEnum lcafType, short length) {
146 super(AddressFamilyIdentifierEnum.LCAF);
147 this.lcafType = lcafType;
148 this.reserved1 = 0;
149 this.reserved2 = 0;
150 this.flag = 0;
151 this.length = length;
152 }
153
154 /**
155 * Initializes LCAF address.
156 *
157 * @param lcafType LCAF type
Jian Lic7e20a52016-07-18 19:03:49 +0900158 */
159 protected LispLcafAddress(LispCanonicalAddressFormatEnum lcafType) {
160 super(AddressFamilyIdentifierEnum.LCAF);
161 this.lcafType = lcafType;
162 this.reserved1 = 0;
163 this.reserved2 = 0;
164 this.flag = 0;
165 this.length = 0;
Jian Li09596002016-07-15 17:46:49 +0900166 }
167
168 /**
169 * Obtains LCAF type.
170 *
171 * @return LCAF type
172 */
173 public LispCanonicalAddressFormatEnum getType() {
174 return lcafType;
175 }
176
177 /**
Jian Lic7e20a52016-07-18 19:03:49 +0900178 * Obtains LCAF reserved1 value.
Jian Li09596002016-07-15 17:46:49 +0900179 *
Jian Lic7e20a52016-07-18 19:03:49 +0900180 * @return LCAF reserved1 value
Jian Li09596002016-07-15 17:46:49 +0900181 */
Jian Lic7e20a52016-07-18 19:03:49 +0900182 public byte getReserved1() {
183 return reserved1;
184 }
185
186 /**
187 * Obtains LCAF reserved2 value.
188 *
189 * @return LCAF reserved2 value
190 */
191 public byte getReserved2() {
192 return reserved2;
193 }
194
195 /**
196 * Obtains LCAF flag value.
197 *
198 * @return LCAF flag value
199 */
200 public byte getFlag() {
201 return flag;
202 }
203
204 /**
205 * Obtains LCAF length value.
206 *
207 * @return LCAF length value
208 */
Jian Lia7b394d2016-08-21 23:11:46 +0900209 public short getLength() {
Jian Lic7e20a52016-07-18 19:03:49 +0900210 return length;
Jian Li09596002016-07-15 17:46:49 +0900211 }
212
Jian Lia7b394d2016-08-21 23:11:46 +0900213 /**
214 * Deserializes common fields from byte buffer.
215 *
216 * @param byteBuf byte buffer
217 * @return LispLcafAddress with filled common data fields
218 */
219 public static LispLcafAddress deserializeCommon(ByteBuf byteBuf) {
220
Jian Lib9e1ac72016-11-07 21:15:17 +0900221 // let's skip first and second two bytes
,
222 // because it represents LCAF AFI code
223 byteBuf.skipBytes(LCAF_AFI_CODE_BYTE_LENGTH);
224
Jian Lia7b394d2016-08-21 23:11:46 +0900225 // reserved1 -> 8 bits
226 byte reserved1 = (byte) byteBuf.readUnsignedByte();
227
228 // flags -> 8 bits
229 byte flag = (byte) byteBuf.readUnsignedByte();
230
231 // LCAF type -> 8 bits
232 byte lcafType = (byte) byteBuf.readUnsignedByte();
233
234 // reserved2 -> 8bits
235 byte reserved2 = (byte) byteBuf.readUnsignedByte();
236
237 // length -> 16 bits
238 short length = (short) byteBuf.readUnsignedShort();
239
240 return new LispLcafAddress(LispCanonicalAddressFormatEnum.valueOf(lcafType),
Jian Lib9e1ac72016-11-07 21:15:17 +0900241 reserved1, reserved2, flag, length);
Jian Lia7b394d2016-08-21 23:11:46 +0900242 }
243
GUNiba871702016-08-22 21:06:02 +0900244 /**
Jian Lief0f7232016-11-15 19:55:46 +0900245 * Updates the header length field value based on the size of LISP header.
246 *
247 * @param lcafIndex the index of LCAF address, because LCAF address is
248 * contained inside LISP control message, so to correctly
249 * find the right LCAF length index, we need to know the
250 * absolute lcaf index inside LISP control message byte buf
251 * @param byteBuf netty byte buffer
252 */
253 public static void updateLength(int lcafIndex, ByteBuf byteBuf) {
yoonseon980cd7c2016-11-18 14:18:46 -0800254 byteBuf.setByte(lcafIndex + LENGTH_FIELD_INDEX,
255 byteBuf.writerIndex() - COMMON_HEADER_SIZE - lcafIndex);
Jian Lief0f7232016-11-15 19:55:46 +0900256 }
257
258 /**
GUNiba871702016-08-22 21:06:02 +0900259 * Serializes common fields to byte buffer.
260 *
261 * @param byteBuf byte buffer
262 * @param address LISP LCAF address instance
263 */
264 public static void serializeCommon(ByteBuf byteBuf, LispLcafAddress address) {
Jian Lief0f7232016-11-15 19:55:46 +0900265
Jian Lib9e1ac72016-11-07 21:15:17 +0900266 byteBuf.writeShort(AddressFamilyIdentifierEnum.LCAF.getIanaCode());
GUNiba871702016-08-22 21:06:02 +0900267 byteBuf.writeByte(address.getReserved1());
268 byteBuf.writeByte(address.getFlag());
269 byteBuf.writeByte(address.getType().getLispCode());
270 byteBuf.writeByte(address.getReserved2());
271 byteBuf.writeShort(address.getLength());
272 }
273
Jian Li09596002016-07-15 17:46:49 +0900274 @Override
275 public int hashCode() {
Jian Lid56f97e2016-07-19 15:48:15 +0900276 return Objects.hash(lcafType, reserved1, reserved2, flag, length);
Jian Li09596002016-07-15 17:46:49 +0900277 }
278
279 @Override
280 public boolean equals(Object obj) {
281 if (this == obj) {
282 return true;
283 }
284
285 if (obj instanceof LispLcafAddress) {
286 final LispLcafAddress other = (LispLcafAddress) obj;
287 return Objects.equals(this.lcafType, other.lcafType) &&
Jian Lib9e1ac72016-11-07 21:15:17 +0900288 Objects.equals(this.reserved1, other.reserved1) &&
289 Objects.equals(this.reserved2, other.reserved2) &&
290 Objects.equals(this.flag, other.flag) &&
291 Objects.equals(this.length, other.length);
Jian Li09596002016-07-15 17:46:49 +0900292 }
293 return false;
294 }
295
296 @Override
297 public String toString() {
298 return toStringHelper(this)
299 .add("lcafType", lcafType)
Jian Lic7e20a52016-07-18 19:03:49 +0900300 .add("reserved1", reserved1)
301 .add("reserved2", reserved2)
302 .add("flag", flag)
303 .add("length", length)
Jian Li09596002016-07-15 17:46:49 +0900304 .toString();
305 }
Jian Lia7b394d2016-08-21 23:11:46 +0900306
307 protected static class LcafAddressBuilder<T> {
308
309 protected byte reserved1;
310 protected byte flag;
311 protected byte lcafType;
312 protected byte reserved2;
313 protected short length;
314
315 /**
316 * Sets reserved1 value.
317 *
318 * @param reserved1 reserved1 value
319 * @return LcafAddressBuilder object
320 */
321 public T withReserved1(byte reserved1) {
322 this.reserved1 = reserved1;
323 return (T) this;
324 }
325
326 /**
327 * Sets flag.
328 *
329 * @param flag flag boolean
330 * @return LcafAddressBuilder object
331 */
332 public T withFlag(byte flag) {
333 this.flag = flag;
334 return (T) this;
335 }
336
337 /**
338 * Sets LCAF type.
339 *
340 * @param lcafType LCAF type
341 * @return LcafAddressBuilder object
342 */
343 public T withLcafType(byte lcafType) {
344 this.lcafType = lcafType;
345 return (T) this;
346 }
347
348 /**
349 * Sets reserved2 value.
350 *
351 * @param reserved2 reserved2 value
352 * @return LcafAddressBuilder object
353 */
354 public T withReserved2(byte reserved2) {
355 this.reserved2 = reserved2;
356 return (T) this;
357 }
358
359 /**
360 * Sets length value.
361 *
362 * @param length length value
363 * @return LcafAddressBuilder object
364 */
365 public T withLength(short length) {
366 this.length = length;
367 return (T) this;
368 }
369
370 /**
371 * Builds LispLcafAddress object.
372 *
373 * @return LispLcafAddress instance
374 */
375 public LispLcafAddress build() {
yoonseon980cd7c2016-11-18 14:18:46 -0800376 return new LispLcafAddress(LispCanonicalAddressFormatEnum
377 .valueOf(lcafType),
378 reserved1, reserved2, flag, length);
Jian Lia7b394d2016-08-21 23:11:46 +0900379 }
380 }
381
GUNiba871702016-08-22 21:06:02 +0900382 /**
383 * LISP LCAF reader class.
384 */
yoonseon980cd7c2016-11-18 14:18:46 -0800385 public static class LcafAddressReader
386 implements LispAddressReader<LispLcafAddress> {
Jian Lia7b394d2016-08-21 23:11:46 +0900387
388 private static final int LCAF_TYPE_FIELD_INDEX = 4;
389
390 @Override
yoonseon980cd7c2016-11-18 14:18:46 -0800391 public LispLcafAddress readFrom(ByteBuf byteBuf)
392 throws LispParseError, LispReaderException {
Jian Lia7b394d2016-08-21 23:11:46 +0900393
394 int index = byteBuf.readerIndex();
395
396 // LCAF type -> 8 bits
Jian Li55ddcdb2016-11-21 17:04:01 +0900397 byte lcafType = (byte) byteBuf.getUnsignedByte(index + LCAF_TYPE_FIELD_INDEX);
Jian Lia7b394d2016-08-21 23:11:46 +0900398
399 if (lcafType == APPLICATION_DATA.getLispCode()) {
Jian Lif31019a2017-02-05 07:57:46 +0900400 return new LispAppDataLcafAddress.AppDataLcafAddressReader().readFrom(byteBuf);
Jian Li55ddcdb2016-11-21 17:04:01 +0900401 }
402
403 if (lcafType == NAT.getLispCode()) {
Jian Lif31019a2017-02-05 07:57:46 +0900404 return new LispNatLcafAddress.NatLcafAddressReader().readFrom(byteBuf);
Jian Lia7b394d2016-08-21 23:11:46 +0900405 }
406
407 if (lcafType == LIST.getLispCode()) {
Jian Lif31019a2017-02-05 07:57:46 +0900408 return new LispListLcafAddress.ListLcafAddressReader().readFrom(byteBuf);
Jian Lia7b394d2016-08-21 23:11:46 +0900409 }
410
411 if (lcafType == SEGMENT.getLispCode()) {
Jian Lif31019a2017-02-05 07:57:46 +0900412 return new LispSegmentLcafAddress.SegmentLcafAddressReader().readFrom(byteBuf);
Jian Lia7b394d2016-08-21 23:11:46 +0900413 }
414
Jian Li2af9eaa2017-02-05 09:15:07 +0900415 if (lcafType == MULTICAST.getLispCode()) {
416 return new LispMulticastLcafAddress.MulticastLcafAddressReader().readFrom(byteBuf);
417 }
418
Jian Lia7b394d2016-08-21 23:11:46 +0900419 if (lcafType == SOURCE_DEST.getLispCode()) {
Jian Lif31019a2017-02-05 07:57:46 +0900420 return new LispSourceDestLcafAddress.SourceDestLcafAddressReader().readFrom(byteBuf);
Jian Lia7b394d2016-08-21 23:11:46 +0900421 }
422
Jian Li99f83ef2016-11-03 19:14:25 +0100423 if (lcafType == TRAFFIC_ENGINEERING.getLispCode()) {
Jian Lif31019a2017-02-05 07:57:46 +0900424 return new LispTeLcafAddress.TeLcafAddressReader().readFrom(byteBuf);
Jian Li99f83ef2016-11-03 19:14:25 +0100425 }
426
Jian Lid4e63702016-08-30 18:29:20 +0900427 log.warn("Unsupported LCAF type, please specify a correct LCAF type");
428
Jian Lia7b394d2016-08-21 23:11:46 +0900429 return null;
430 }
431 }
GUNiba871702016-08-22 21:06:02 +0900432
433 /**
434 * LISP LCAF address writer class.
435 */
yoonseon980cd7c2016-11-18 14:18:46 -0800436 public static class LcafAddressWriter
437 implements LispAddressWriter<LispLcafAddress> {
GUNiba871702016-08-22 21:06:02 +0900438
439 @Override
yoonseon980cd7c2016-11-18 14:18:46 -0800440 public void writeTo(ByteBuf byteBuf, LispLcafAddress address)
441 throws LispWriterException {
GUNiba871702016-08-22 21:06:02 +0900442 switch (address.getType()) {
443 case APPLICATION_DATA:
Jian Lif31019a2017-02-05 07:57:46 +0900444 new LispAppDataLcafAddress.AppDataLcafAddressWriter().writeTo(byteBuf,
Jian Li55ddcdb2016-11-21 17:04:01 +0900445 (LispAppDataLcafAddress) address);
446 break;
447 case NAT:
Jian Lif31019a2017-02-05 07:57:46 +0900448 new LispNatLcafAddress.NatLcafAddressWriter().writeTo(byteBuf,
Jian Li55ddcdb2016-11-21 17:04:01 +0900449 (LispNatLcafAddress) address);
GUNiba871702016-08-22 21:06:02 +0900450 break;
451 case LIST:
Jian Lif31019a2017-02-05 07:57:46 +0900452 new LispListLcafAddress.ListLcafAddressWriter().writeTo(byteBuf,
GUNiba871702016-08-22 21:06:02 +0900453 (LispListLcafAddress) address);
454 break;
455 case SEGMENT:
Jian Lif31019a2017-02-05 07:57:46 +0900456 new LispSegmentLcafAddress.SegmentLcafAddressWriter().writeTo(byteBuf,
Jian Li55ddcdb2016-11-21 17:04:01 +0900457 (LispSegmentLcafAddress) address);
GUNiba871702016-08-22 21:06:02 +0900458 break;
Jian Li2af9eaa2017-02-05 09:15:07 +0900459 case MULTICAST:
460 new LispMulticastLcafAddress.MulticastLcafAddressWriter().writeTo(byteBuf,
461 (LispMulticastLcafAddress) address);
462 break;
GUNiba871702016-08-22 21:06:02 +0900463 case SOURCE_DEST:
Jian Lif31019a2017-02-05 07:57:46 +0900464 new LispSourceDestLcafAddress.SourceDestLcafAddressWriter().writeTo(byteBuf,
Jian Li55ddcdb2016-11-21 17:04:01 +0900465 (LispSourceDestLcafAddress) address);
GUNiba871702016-08-22 21:06:02 +0900466 break;
Jian Li99f83ef2016-11-03 19:14:25 +0100467 case TRAFFIC_ENGINEERING:
Jian Lif31019a2017-02-05 07:57:46 +0900468 new LispTeLcafAddress.TeLcafAddressWriter().writeTo(byteBuf,
Jian Li99f83ef2016-11-03 19:14:25 +0100469 (LispTeLcafAddress) address);
470 break;
Jian Lid4e63702016-08-30 18:29:20 +0900471 default:
472 log.warn("Unsupported LCAF type, please specify a correct LCAF type");
473 break;
GUNiba871702016-08-22 21:06:02 +0900474 }
475 }
476 }
Jian Li09596002016-07-15 17:46:49 +0900477}