blob: 45e85bf48629eba1f0d71276e80c304fe5de92ab [file] [log] [blame]
Jian Li451175e2016-07-19 23:22:20 +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.protocols;
17
Jian Li20850d32016-08-04 02:15:57 +090018import com.google.common.base.Objects;
Jian Lif59c0ad2016-08-02 18:11:30 +090019import com.google.common.collect.ImmutableList;
20import com.google.common.collect.Lists;
Jian Li451175e2016-07-19 23:22:20 +090021import io.netty.buffer.ByteBuf;
Jian Li47671902016-08-11 01:18:18 +090022import org.onlab.util.ByteOperator;
Jian Li26069e22016-08-10 22:00:52 +090023import org.onosproject.lisp.msg.exceptions.LispParseError;
Jian Lia7b394d2016-08-21 23:11:46 +090024import org.onosproject.lisp.msg.exceptions.LispReaderException;
Jian Liedc5db12016-08-23 17:30:19 +090025import org.onosproject.lisp.msg.exceptions.LispWriterException;
Jian Li719b3bf2016-07-22 00:38:29 +090026import org.onosproject.lisp.msg.types.LispAfiAddress;
27
28import java.util.List;
Jian Li451175e2016-07-19 23:22:20 +090029
Jian Li20850d32016-08-04 02:15:57 +090030import static com.google.common.base.MoreObjects.toStringHelper;
Jian Liedc5db12016-08-23 17:30:19 +090031import static org.onosproject.lisp.msg.types.LispAfiAddress.AfiAddressWriter;
32import static org.onosproject.lisp.msg.protocols.LispEidRecord.EidRecordWriter;
Jian Li20850d32016-08-04 02:15:57 +090033
Jian Li451175e2016-07-19 23:22:20 +090034/**
35 * Default LISP map request message class.
36 */
Jian Lif59c0ad2016-08-02 18:11:30 +090037public final class DefaultLispMapRequest implements LispMapRequest {
38
39 private final long nonce;
40 private final byte recordCount;
41 private final LispAfiAddress sourceEid;
42 private final List<LispAfiAddress> itrRlocs;
43 private final List<LispEidRecord> eidRecords;
44 private final boolean authoritative;
45 private final boolean mapDataPresent;
46 private final boolean probe;
47 private final boolean smr;
48 private final boolean pitr;
49 private final boolean smrInvoked;
50
51 /**
52 * A private constructor that protects object instantiation from external.
53 *
54 * @param nonce nonce
55 * @param recordCount record count number
56 * @param sourceEid source EID address
57 * @param itrRlocs a collection of ITR RLOCs
58 * @param eidRecords a collection of EID records
59 * @param authoritative authoritative flag
60 * @param mapDataPresent map data present flag
61 * @param probe probe flag
62 * @param smr smr flag
63 * @param pitr pitr flag
64 * @param smrInvoked smrInvoked flag
65 */
66 private DefaultLispMapRequest(long nonce, byte recordCount, LispAfiAddress sourceEid,
67 List<LispAfiAddress> itrRlocs, List<LispEidRecord> eidRecords,
68 boolean authoritative, boolean mapDataPresent, boolean probe,
69 boolean smr, boolean pitr, boolean smrInvoked) {
70 this.nonce = nonce;
71 this.recordCount = recordCount;
72 this.sourceEid = sourceEid;
73 this.itrRlocs = itrRlocs;
74 this.eidRecords = eidRecords;
75 this.authoritative = authoritative;
76 this.mapDataPresent = mapDataPresent;
77 this.probe = probe;
78 this.smr = smr;
79 this.pitr = pitr;
80 this.smrInvoked = smrInvoked;
81 }
82
Jian Li451175e2016-07-19 23:22:20 +090083 @Override
84 public LispType getType() {
Jian Lif59c0ad2016-08-02 18:11:30 +090085 return LispType.LISP_MAP_REQUEST;
Jian Li451175e2016-07-19 23:22:20 +090086 }
87
88 @Override
89 public void writeTo(ByteBuf byteBuf) {
Jian Lif59c0ad2016-08-02 18:11:30 +090090 // TODO: serialize LispMapRequest message
Jian Li451175e2016-07-19 23:22:20 +090091 }
92
93 @Override
94 public Builder createBuilder() {
Jian Li525fded2016-08-04 01:15:33 +090095 return new DefaultRequestBuilder();
Jian Li451175e2016-07-19 23:22:20 +090096 }
Jian Li719b3bf2016-07-22 00:38:29 +090097
98 @Override
99 public boolean isAuthoritative() {
Jian Liedc5db12016-08-23 17:30:19 +0900100 return authoritative;
Jian Lif59c0ad2016-08-02 18:11:30 +0900101 }
102
103 @Override
104 public boolean isMapDataPresent() {
Jian Liedc5db12016-08-23 17:30:19 +0900105 return mapDataPresent;
Jian Li719b3bf2016-07-22 00:38:29 +0900106 }
107
108 @Override
109 public boolean isProbe() {
Jian Liedc5db12016-08-23 17:30:19 +0900110 return probe;
Jian Li719b3bf2016-07-22 00:38:29 +0900111 }
112
113 @Override
114 public boolean isSmr() {
Jian Liedc5db12016-08-23 17:30:19 +0900115 return smr;
Jian Li719b3bf2016-07-22 00:38:29 +0900116 }
117
118 @Override
119 public boolean isPitr() {
Jian Liedc5db12016-08-23 17:30:19 +0900120 return pitr;
Jian Li719b3bf2016-07-22 00:38:29 +0900121 }
122
123 @Override
124 public boolean isSmrInvoked() {
Jian Liedc5db12016-08-23 17:30:19 +0900125 return smrInvoked;
Jian Li719b3bf2016-07-22 00:38:29 +0900126 }
127
128 @Override
129 public byte getRecordCount() {
Jian Liedc5db12016-08-23 17:30:19 +0900130 return recordCount;
Jian Li719b3bf2016-07-22 00:38:29 +0900131 }
132
133 @Override
134 public long getNonce() {
Jian Liedc5db12016-08-23 17:30:19 +0900135 return nonce;
Jian Li719b3bf2016-07-22 00:38:29 +0900136 }
137
138 @Override
139 public LispAfiAddress getSourceEid() {
Jian Liedc5db12016-08-23 17:30:19 +0900140 return sourceEid;
Jian Li719b3bf2016-07-22 00:38:29 +0900141 }
142
143 @Override
144 public List<LispAfiAddress> getItrRlocs() {
Jian Lif59c0ad2016-08-02 18:11:30 +0900145 return ImmutableList.copyOf(itrRlocs);
Jian Li719b3bf2016-07-22 00:38:29 +0900146 }
147
148 @Override
Jian Li10a09062016-07-26 23:58:50 +0900149 public List<LispEidRecord> getEids() {
Jian Lif59c0ad2016-08-02 18:11:30 +0900150 return ImmutableList.copyOf(eidRecords);
Jian Li719b3bf2016-07-22 00:38:29 +0900151 }
152
Jian Li20850d32016-08-04 02:15:57 +0900153 @Override
154 public String toString() {
155 return toStringHelper(this)
156 .add("type", getType())
157 .add("nonce", nonce)
158 .add("recordCount", recordCount)
159 .add("source EID", sourceEid)
160 .add("ITR rlocs", itrRlocs)
161 .add("EID records", eidRecords)
162 .add("authoritative", authoritative)
163 .add("mapDataPresent", mapDataPresent)
164 .add("probe", probe)
165 .add("SMR", smr)
166 .add("Proxy ITR", pitr)
167 .add("SMR Invoked", smrInvoked).toString();
168 }
169
170 @Override
171 public boolean equals(Object o) {
172 if (this == o) {
173 return true;
174 }
175 if (o == null || getClass() != o.getClass()) {
176 return false;
177 }
178 DefaultLispMapRequest that = (DefaultLispMapRequest) o;
179 return Objects.equal(nonce, that.nonce) &&
180 Objects.equal(recordCount, that.recordCount) &&
181 Objects.equal(sourceEid, that.sourceEid) &&
182 Objects.equal(itrRlocs, that.itrRlocs) &&
183 Objects.equal(eidRecords, that.eidRecords) &&
184 Objects.equal(authoritative, that.authoritative) &&
185 Objects.equal(mapDataPresent, that.mapDataPresent) &&
186 Objects.equal(probe, that.probe) &&
187 Objects.equal(smr, that.smr) &&
188 Objects.equal(pitr, that.pitr) &&
189 Objects.equal(smrInvoked, that.smrInvoked);
190 }
191
192 @Override
193 public int hashCode() {
194 return Objects.hashCode(nonce, recordCount, sourceEid, itrRlocs, eidRecords,
195 authoritative, mapDataPresent, probe, smr, pitr, smrInvoked);
196 }
197
Jian Li719b3bf2016-07-22 00:38:29 +0900198 public static final class DefaultRequestBuilder implements RequestBuilder {
199
Jian Lif59c0ad2016-08-02 18:11:30 +0900200 private long nonce;
201 private byte recordCount;
202 private LispAfiAddress sourceEid;
203 private List<LispAfiAddress> itrRlocs = Lists.newArrayList();
204 private List<LispEidRecord> eidRecords = Lists.newArrayList();
205 private boolean authoritative;
206 private boolean mapDataPresent;
207 private boolean probe;
208 private boolean smr;
209 private boolean pitr;
210 private boolean smrInvoked;
Jian Li719b3bf2016-07-22 00:38:29 +0900211
212 @Override
213 public LispType getType() {
Jian Lif59c0ad2016-08-02 18:11:30 +0900214 return LispType.LISP_MAP_REQUEST;
Jian Li719b3bf2016-07-22 00:38:29 +0900215 }
216
217 @Override
Jian Lif59c0ad2016-08-02 18:11:30 +0900218 public RequestBuilder withIsAuthoritative(boolean authoritative) {
219 this.authoritative = authoritative;
220 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900221 }
222
223 @Override
Jian Lif59c0ad2016-08-02 18:11:30 +0900224 public RequestBuilder withIsProbe(boolean probe) {
225 this.probe = probe;
226 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900227 }
228
229 @Override
Jian Lif59c0ad2016-08-02 18:11:30 +0900230 public RequestBuilder withIsMapDataPresent(boolean mapDataPresent) {
231 this.mapDataPresent = mapDataPresent;
232 return this;
233 }
234
Jian Lif59c0ad2016-08-02 18:11:30 +0900235 @Override
236 public RequestBuilder withIsSmr(boolean smr) {
237 this.smr = smr;
238 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900239 }
240
241 @Override
Jian Lif59c0ad2016-08-02 18:11:30 +0900242 public RequestBuilder withIsPitr(boolean pitr) {
243 this.pitr = pitr;
244 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900245 }
246
247 @Override
Jian Lif59c0ad2016-08-02 18:11:30 +0900248 public RequestBuilder withIsSmrInvoked(boolean smrInvoked) {
249 this.smrInvoked = smrInvoked;
250 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900251 }
252
253 @Override
254 public RequestBuilder withRecordCount(byte recordCount) {
Jian Lif59c0ad2016-08-02 18:11:30 +0900255 this.recordCount = recordCount;
256 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900257 }
258
259 @Override
260 public RequestBuilder withNonce(long nonce) {
Jian Lif59c0ad2016-08-02 18:11:30 +0900261 this.nonce = nonce;
262 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900263 }
264
265 @Override
Jian Lif59c0ad2016-08-02 18:11:30 +0900266 public RequestBuilder withSourceEid(LispAfiAddress sourceEid) {
267 this.sourceEid = sourceEid;
268 return this;
269 }
270
271 @Override
Jian Li47671902016-08-11 01:18:18 +0900272 public RequestBuilder withItrRlocs(List<LispAfiAddress> itrRlocs) {
273 this.itrRlocs = ImmutableList.copyOf(itrRlocs);
Jian Lif59c0ad2016-08-02 18:11:30 +0900274 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900275 }
276
277 @Override
Jian Li47671902016-08-11 01:18:18 +0900278 public RequestBuilder withEidRecords(List<LispEidRecord> records) {
279 this.eidRecords = ImmutableList.copyOf(records);
Jian Lif59c0ad2016-08-02 18:11:30 +0900280 return this;
281 }
282
283 @Override
Jian Li525fded2016-08-04 01:15:33 +0900284 public LispMapRequest build() {
Jian Lif59c0ad2016-08-02 18:11:30 +0900285 return new DefaultLispMapRequest(nonce, recordCount, sourceEid, itrRlocs,
286 eidRecords, authoritative, mapDataPresent, probe, smr, pitr, smrInvoked);
Jian Li719b3bf2016-07-22 00:38:29 +0900287 }
288 }
Jian Li26069e22016-08-10 22:00:52 +0900289
290 /**
Jian Liedc5db12016-08-23 17:30:19 +0900291 * A LISP message reader for MapRequest message.
Jian Li26069e22016-08-10 22:00:52 +0900292 */
Jian Liedc5db12016-08-23 17:30:19 +0900293 public static final class RequestReader implements LispMessageReader<LispMapRequest> {
Jian Li26069e22016-08-10 22:00:52 +0900294
Jian Li47671902016-08-11 01:18:18 +0900295 private static final int AUTHORITATIVE_INDEX = 3;
296 private static final int MAP_DATA_PRESENT_INDEX = 2;
297 private static final int PROBE_INDEX = 1;
298 private static final int SMR_INDEX = 0;
299 private static final int PITR_INDEX = 7;
300 private static final int SMR_INVOKED_INDEX = 6;
301
Jian Li26069e22016-08-10 22:00:52 +0900302 @Override
Jian Lia7b394d2016-08-21 23:11:46 +0900303 public LispMapRequest readFrom(ByteBuf byteBuf) throws LispParseError, LispReaderException {
Jian Li47671902016-08-11 01:18:18 +0900304
305 if (byteBuf.readerIndex() != 0) {
306 return null;
307 }
308
309 byte typeWithFlags = byteBuf.readByte();
310
311 // authoritative -> 1 bit
312 boolean authoritative = ByteOperator.getBit(typeWithFlags, AUTHORITATIVE_INDEX);
313
314 // mapDataPresent -> 1 bit
315 boolean mapDataPresent = ByteOperator.getBit(typeWithFlags, MAP_DATA_PRESENT_INDEX);
316
317 // probe -> 1 bit
318 boolean probe = ByteOperator.getBit(typeWithFlags, PROBE_INDEX);
319
320 // smr -> 1 bit
321 boolean smr = ByteOperator.getBit(typeWithFlags, SMR_INDEX);
322
323 byte reservedWithFlags = byteBuf.readByte();
324
325 // pitr -> 1 bit
326 boolean pitr = ByteOperator.getBit(reservedWithFlags, PITR_INDEX);
327
328 // smrInvoked -> 1 bit
329 boolean smrInvoked = ByteOperator.getBit(reservedWithFlags, SMR_INVOKED_INDEX);
330
331 // let's skip reserved field, only obtains ITR counter value
332 // assume that first 3 bits are all set as 0,
333 // remain 5 bits represent Itr Rloc Counter (IRC)
334 int irc = byteBuf.readUnsignedShort();
335
336 // record count -> 8 bits
337 int recordCount = byteBuf.readUnsignedShort();
338
339 // nonce -> 64 bits
340 long nonce = byteBuf.readLong();
341
Jian Lia7b394d2016-08-21 23:11:46 +0900342 LispAfiAddress sourceEid = new LispAfiAddress.AfiAddressReader().readFrom(byteBuf);
Jian Li47671902016-08-11 01:18:18 +0900343
Jian Lia7b394d2016-08-21 23:11:46 +0900344 // deserialize a collection of RLOC addresses
345 List<LispAfiAddress> itrRlocs = Lists.newArrayList();
346 for (int i = 0; i < irc; i++) {
347 itrRlocs.add(new LispAfiAddress.AfiAddressReader().readFrom(byteBuf));
348 }
Jian Li47671902016-08-11 01:18:18 +0900349
Jian Lia7b394d2016-08-21 23:11:46 +0900350 // deserialize a collection of EID records
351 List<LispEidRecord> eidRecords = Lists.newArrayList();
352 for (int i = 0; i < recordCount; i++) {
353 eidRecords.add(new LispEidRecord.EidRecordReader().readFrom(byteBuf));
354 }
Jian Li47671902016-08-11 01:18:18 +0900355
356 return new DefaultRequestBuilder()
357 .withIsAuthoritative(authoritative)
358 .withIsMapDataPresent(mapDataPresent)
359 .withIsProbe(probe)
360 .withIsSmr(smr)
361 .withIsPitr(pitr)
362 .withIsSmrInvoked(smrInvoked)
363 .withNonce(nonce)
364 .withRecordCount((byte) recordCount)
Jian Lia7b394d2016-08-21 23:11:46 +0900365 .withSourceEid(sourceEid)
366 .withEidRecords(eidRecords)
367 .withItrRlocs(itrRlocs)
Jian Li47671902016-08-11 01:18:18 +0900368 .build();
Jian Li26069e22016-08-10 22:00:52 +0900369 }
370 }
Jian Liedc5db12016-08-23 17:30:19 +0900371
372 /**
373 * A LISP message writer for MapRequest message.
374 */
375 public static final class RequestWriter implements LispMessageWriter<LispMapRequest> {
376
377 private static final int REQUEST_MSG_TYPE = 1;
378 private static final int REQUEST_SHIFT_BIT = 4;
379
380 private static final int AUTHORITATIVE_SHIFT_BIT = 3;
381 private static final int MAP_DATA_PRESENT_SHIFT_BIT = 2;
382 private static final int PROBE_SHIFT_BIT = 1;
383
384 private static final int PITR_SHIFT_BIT = 7;
385 private static final int SMR_INVOKED_SHIFT_BIT = 6;
386
387 private static final int ENABLE_BIT = 1;
388 private static final int DISABLE_BIT = 0;
389
390 private static final int UNUSED_ZERO = 0;
391
392 @Override
393 public void writeTo(ByteBuf byteBuf, LispMapRequest message) throws LispWriterException {
394
395 // specify LISP message type
396 byte msgType = (byte) (REQUEST_MSG_TYPE << REQUEST_SHIFT_BIT);
397
398 // authoritative flag
399 byte authoritative = DISABLE_BIT;
400 if (message.isAuthoritative()) {
401 authoritative = (byte) (ENABLE_BIT << AUTHORITATIVE_SHIFT_BIT);
402 }
403
404 // map data present flag
405 byte mapDataPresent = DISABLE_BIT;
406 if (message.isMapDataPresent()) {
407 mapDataPresent = (byte) (ENABLE_BIT << MAP_DATA_PRESENT_SHIFT_BIT);
408 }
409
410 // probe flag
411 byte probe = DISABLE_BIT;
412 if (message.isProbe()) {
413 probe = (byte) (ENABLE_BIT << PROBE_SHIFT_BIT);
414 }
415
416 // SMR flag
417 byte smr = DISABLE_BIT;
418 if (message.isSmr()) {
419 smr = (byte) ENABLE_BIT;
420 }
421
422 byteBuf.writeByte((byte) (msgType + authoritative + mapDataPresent + probe + smr));
423
424 // PITR flag bit
425 byte pitr = DISABLE_BIT;
426 if (message.isPitr()) {
427 pitr = (byte) (ENABLE_BIT << PITR_SHIFT_BIT);
428 }
429
430 // SMR invoked flag bit
431 byte smrInvoked = DISABLE_BIT;
432 if (message.isSmrInvoked()) {
433 smrInvoked = (byte) (ENABLE_BIT << SMR_INVOKED_SHIFT_BIT);
434 }
435
436 byteBuf.writeByte((byte) (pitr + smrInvoked));
437
438 // TODO: ITR RLOC count
439 byteBuf.writeByte((byte) UNUSED_ZERO);
440
441 // record count
442 byteBuf.writeByte(message.getRecordCount());
443
444 // nonce
445 byteBuf.writeLong(message.getNonce());
446
447 // Source EID AFI with Source EID address
448 AfiAddressWriter afiAddressWriter = new AfiAddressWriter();
449 afiAddressWriter.writeTo(byteBuf, message.getSourceEid());
450
451 // ITR RLOCs
452 List<LispAfiAddress> rlocs = message.getItrRlocs();
453 for (int i = 0; i < rlocs.size(); i++) {
454 afiAddressWriter.writeTo(byteBuf, rlocs.get(i));
455 }
456
457 // EID records
458 EidRecordWriter recordWriter = new EidRecordWriter();
459 List<LispEidRecord> records = message.getEids();
460
461 for (int i = 0; i < records.size(); i++) {
462 recordWriter.writeTo(byteBuf, records.get(i));
463 }
464
465 // TODO: handle Map-Reply record
466 }
467 }
Jian Li451175e2016-07-19 23:22:20 +0900468}