blob: 1997bcc59520652fcc894334b8545308ce31ece7 [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 Lic7e20a52016-07-18 19:03:49 +090032 *
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
54 /**
55 * Initializes LCAF address.
56 *
57 * @param lcafType LCAF type
Jian Lic7e20a52016-07-18 19:03:49 +090058 * @param reserved1 reserved1 field
59 * @param reserved2 reserved2 field
60 * @param flag flag field
61 * @param length length field
Jian Li09596002016-07-15 17:46:49 +090062 */
Jian Lic7e20a52016-07-18 19:03:49 +090063 protected LispLcafAddress(LispCanonicalAddressFormatEnum lcafType,
Jian Lia7b394d2016-08-21 23:11:46 +090064 byte reserved1, byte reserved2, byte flag, short length) {
Jian Li09596002016-07-15 17:46:49 +090065 super(AddressFamilyIdentifierEnum.LCAF);
66 this.lcafType = lcafType;
Jian Lic7e20a52016-07-18 19:03:49 +090067 this.reserved1 = reserved1;
68 this.reserved2 = reserved2;
69 this.flag = flag;
70 this.length = length;
71 }
72
73 /**
74 * Initializes LCAF address.
75 *
76 * @param lcafType LCAF type
77 * @param reserved2 reserved2 field
78 * @param flag flag field
79 * @param length length field
80 */
81 protected LispLcafAddress(LispCanonicalAddressFormatEnum lcafType,
Jian Lia7b394d2016-08-21 23:11:46 +090082 byte reserved2, byte flag, short length) {
Jian Lic7e20a52016-07-18 19:03:49 +090083 super(AddressFamilyIdentifierEnum.LCAF);
84 this.lcafType = lcafType;
85 this.reserved2 = reserved2;
86 this.flag = flag;
87 this.length = length;
88 this.reserved1 = 0;
89 }
90
91 /**
92 * Initializes LCAF address.
93 *
94 * @param lcafType LCAF type
95 * @param reserved2 reserved2 field
96 * @param length length field
97 */
98 protected LispLcafAddress(LispCanonicalAddressFormatEnum lcafType,
Jian Lia7b394d2016-08-21 23:11:46 +090099 byte reserved2, short length) {
Jian Lic7e20a52016-07-18 19:03:49 +0900100 super(AddressFamilyIdentifierEnum.LCAF);
101 this.lcafType = lcafType;
102 this.reserved2 = reserved2;
103 this.length = length;
104 this.reserved1 = 0;
105 this.flag = 0;
106 }
107
108 /**
109 * Initializes LCAF address.
110 *
111 * @param lcafType LCAF type
112 * @param reserved2 reserved2 field
113 */
114 protected LispLcafAddress(LispCanonicalAddressFormatEnum lcafType, byte reserved2) {
115 super(AddressFamilyIdentifierEnum.LCAF);
116 this.lcafType = lcafType;
117 this.reserved2 = reserved2;
118 this.reserved1 = 0;
119 this.flag = 0;
120 this.length = 0;
121 }
122
123 /**
124 * Initializes LCAF address.
125 *
126 * @param lcafType LCAF type
Jian Lia7b394d2016-08-21 23:11:46 +0900127 * @param length length field
128 */
129 protected LispLcafAddress(LispCanonicalAddressFormatEnum lcafType, short length) {
130 super(AddressFamilyIdentifierEnum.LCAF);
131 this.lcafType = lcafType;
132 this.reserved1 = 0;
133 this.reserved2 = 0;
134 this.flag = 0;
135 this.length = length;
136 }
137
138 /**
139 * Initializes LCAF address.
140 *
141 * @param lcafType LCAF type
Jian Lic7e20a52016-07-18 19:03:49 +0900142 */
143 protected LispLcafAddress(LispCanonicalAddressFormatEnum lcafType) {
144 super(AddressFamilyIdentifierEnum.LCAF);
145 this.lcafType = lcafType;
146 this.reserved1 = 0;
147 this.reserved2 = 0;
148 this.flag = 0;
149 this.length = 0;
Jian Li09596002016-07-15 17:46:49 +0900150 }
151
152 /**
153 * Obtains LCAF type.
154 *
155 * @return LCAF type
156 */
157 public LispCanonicalAddressFormatEnum getType() {
158 return lcafType;
159 }
160
161 /**
Jian Lic7e20a52016-07-18 19:03:49 +0900162 * Obtains LCAF reserved1 value.
Jian Li09596002016-07-15 17:46:49 +0900163 *
Jian Lic7e20a52016-07-18 19:03:49 +0900164 * @return LCAF reserved1 value
Jian Li09596002016-07-15 17:46:49 +0900165 */
Jian Lic7e20a52016-07-18 19:03:49 +0900166 public byte getReserved1() {
167 return reserved1;
168 }
169
170 /**
171 * Obtains LCAF reserved2 value.
172 *
173 * @return LCAF reserved2 value
174 */
175 public byte getReserved2() {
176 return reserved2;
177 }
178
179 /**
180 * Obtains LCAF flag value.
181 *
182 * @return LCAF flag value
183 */
184 public byte getFlag() {
185 return flag;
186 }
187
188 /**
189 * Obtains LCAF length value.
190 *
191 * @return LCAF length value
192 */
Jian Lia7b394d2016-08-21 23:11:46 +0900193 public short getLength() {
Jian Lic7e20a52016-07-18 19:03:49 +0900194 return length;
Jian Li09596002016-07-15 17:46:49 +0900195 }
196
Jian Lia7b394d2016-08-21 23:11:46 +0900197 /**
198 * Deserializes common fields from byte buffer.
199 *
200 * @param byteBuf byte buffer
201 * @return LispLcafAddress with filled common data fields
202 */
203 public static LispLcafAddress deserializeCommon(ByteBuf byteBuf) {
204
205 // reserved1 -> 8 bits
206 byte reserved1 = (byte) byteBuf.readUnsignedByte();
207
208 // flags -> 8 bits
209 byte flag = (byte) byteBuf.readUnsignedByte();
210
211 // LCAF type -> 8 bits
212 byte lcafType = (byte) byteBuf.readUnsignedByte();
213
214 // reserved2 -> 8bits
215 byte reserved2 = (byte) byteBuf.readUnsignedByte();
216
217 // length -> 16 bits
218 short length = (short) byteBuf.readUnsignedShort();
219
220 return new LispLcafAddress(LispCanonicalAddressFormatEnum.valueOf(lcafType),
221 reserved1, reserved2, flag, length);
222 }
223
GUNiba871702016-08-22 21:06:02 +0900224 /**
225 * Serializes common fields to byte buffer.
226 *
227 * @param byteBuf byte buffer
228 * @param address LISP LCAF address instance
229 */
230 public static void serializeCommon(ByteBuf byteBuf, LispLcafAddress address) {
231 byteBuf.writeByte(address.getReserved1());
232 byteBuf.writeByte(address.getFlag());
233 byteBuf.writeByte(address.getType().getLispCode());
234 byteBuf.writeByte(address.getReserved2());
235 byteBuf.writeShort(address.getLength());
236 }
237
Jian Li09596002016-07-15 17:46:49 +0900238 @Override
239 public int hashCode() {
Jian Lid56f97e2016-07-19 15:48:15 +0900240 return Objects.hash(lcafType, reserved1, reserved2, flag, length);
Jian Li09596002016-07-15 17:46:49 +0900241 }
242
243 @Override
244 public boolean equals(Object obj) {
245 if (this == obj) {
246 return true;
247 }
248
249 if (obj instanceof LispLcafAddress) {
250 final LispLcafAddress other = (LispLcafAddress) obj;
251 return Objects.equals(this.lcafType, other.lcafType) &&
Jian Lic7e20a52016-07-18 19:03:49 +0900252 Objects.equals(this.reserved1, other.reserved1) &&
253 Objects.equals(this.reserved2, other.reserved2) &&
254 Objects.equals(this.flag, other.flag) &&
255 Objects.equals(this.length, other.length);
Jian Li09596002016-07-15 17:46:49 +0900256 }
257 return false;
258 }
259
260 @Override
261 public String toString() {
262 return toStringHelper(this)
263 .add("lcafType", lcafType)
Jian Lic7e20a52016-07-18 19:03:49 +0900264 .add("reserved1", reserved1)
265 .add("reserved2", reserved2)
266 .add("flag", flag)
267 .add("length", length)
Jian Li09596002016-07-15 17:46:49 +0900268 .toString();
269 }
Jian Lia7b394d2016-08-21 23:11:46 +0900270
271 protected static class LcafAddressBuilder<T> {
272
273 protected byte reserved1;
274 protected byte flag;
275 protected byte lcafType;
276 protected byte reserved2;
277 protected short length;
278
279 /**
280 * Sets reserved1 value.
281 *
282 * @param reserved1 reserved1 value
283 * @return LcafAddressBuilder object
284 */
285 public T withReserved1(byte reserved1) {
286 this.reserved1 = reserved1;
287 return (T) this;
288 }
289
290 /**
291 * Sets flag.
292 *
293 * @param flag flag boolean
294 * @return LcafAddressBuilder object
295 */
296 public T withFlag(byte flag) {
297 this.flag = flag;
298 return (T) this;
299 }
300
301 /**
302 * Sets LCAF type.
303 *
304 * @param lcafType LCAF type
305 * @return LcafAddressBuilder object
306 */
307 public T withLcafType(byte lcafType) {
308 this.lcafType = lcafType;
309 return (T) this;
310 }
311
312 /**
313 * Sets reserved2 value.
314 *
315 * @param reserved2 reserved2 value
316 * @return LcafAddressBuilder object
317 */
318 public T withReserved2(byte reserved2) {
319 this.reserved2 = reserved2;
320 return (T) this;
321 }
322
323 /**
324 * Sets length value.
325 *
326 * @param length length value
327 * @return LcafAddressBuilder object
328 */
329 public T withLength(short length) {
330 this.length = length;
331 return (T) this;
332 }
333
334 /**
335 * Builds LispLcafAddress object.
336 *
337 * @return LispLcafAddress instance
338 */
339 public LispLcafAddress build() {
340 return new LispLcafAddress(LispCanonicalAddressFormatEnum.valueOf(lcafType),
341 reserved1, reserved2, flag, length);
342 }
343 }
344
GUNiba871702016-08-22 21:06:02 +0900345 /**
346 * LISP LCAF reader class.
347 */
Jian Lia7b394d2016-08-21 23:11:46 +0900348 public static class LcafAddressReader implements LispAddressReader<LispLcafAddress> {
349
350 private static final int LCAF_TYPE_FIELD_INDEX = 4;
351
352 @Override
353 public LispLcafAddress readFrom(ByteBuf byteBuf) throws LispParseError, LispReaderException {
354
355 int index = byteBuf.readerIndex();
356
357 // LCAF type -> 8 bits
358 byte lcafType = (byte) byteBuf.getUnsignedByte(index + LCAF_TYPE_FIELD_INDEX);
359
360 if (lcafType == APPLICATION_DATA.getLispCode()) {
361 return new LispAppDataLcafAddress.AppDataLcafAddressReader().readFrom(byteBuf);
362 }
363
364 if (lcafType == LIST.getLispCode()) {
365 return new LispListLcafAddress.ListLcafAddressReader().readFrom(byteBuf);
366 }
367
368 if (lcafType == SEGMENT.getLispCode()) {
369 return new LispSegmentLcafAddress.SegmentLcafAddressReader().readFrom(byteBuf);
370 }
371
372 if (lcafType == SOURCE_DEST.getLispCode()) {
373 return new LispSourceDestLcafAddress.SourceDestLcafAddressReader().readFrom(byteBuf);
374 }
375
Jian Li99f83ef2016-11-03 19:14:25 +0100376 if (lcafType == TRAFFIC_ENGINEERING.getLispCode()) {
377 return new LispTeLcafAddress.TeAddressBuilder.TeLcafAddressReader().readFrom(byteBuf);
378 }
379
Jian Lid4e63702016-08-30 18:29:20 +0900380 log.warn("Unsupported LCAF type, please specify a correct LCAF type");
381
Jian Lia7b394d2016-08-21 23:11:46 +0900382 return null;
383 }
384 }
GUNiba871702016-08-22 21:06:02 +0900385
386 /**
387 * LISP LCAF address writer class.
388 */
389 public static class LcafAddressWriter implements LispAddressWriter<LispLcafAddress> {
390
391 @Override
392 public void writeTo(ByteBuf byteBuf, LispLcafAddress address) throws LispWriterException {
393 switch (address.getType()) {
394 case APPLICATION_DATA:
395 new LispAppDataLcafAddress.AppDataLcafAddressWriter().writeTo(byteBuf,
396 (LispAppDataLcafAddress) address);
397 break;
398 case LIST:
399 new LispListLcafAddress.ListLcafAddressWriter().writeTo(byteBuf,
400 (LispListLcafAddress) address);
401 break;
402 case SEGMENT:
403 new LispSegmentLcafAddress.SegmentLcafAddressWriter().writeTo(byteBuf,
404 (LispSegmentLcafAddress) address);
405 break;
406 case SOURCE_DEST:
407 new LispSourceDestLcafAddress.SourceDestLcafAddressWriter().writeTo(byteBuf,
408 (LispSourceDestLcafAddress) address);
409 break;
Jian Li99f83ef2016-11-03 19:14:25 +0100410 case TRAFFIC_ENGINEERING:
411 new LispTeLcafAddress.TeAddressBuilder.TeLcafAddressWriter().writeTo(byteBuf,
412 (LispTeLcafAddress) address);
413 break;
Jian Lid4e63702016-08-30 18:29:20 +0900414 default:
415 log.warn("Unsupported LCAF type, please specify a correct LCAF type");
416 break;
GUNiba871702016-08-22 21:06:02 +0900417 }
418 }
419 }
Jian Li09596002016-07-15 17:46:49 +0900420}