blob: 34ec469c0eb61ac8aff7dbf9b426e83480cae251 [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 Lie4ba2a42016-08-29 20:24:15 +090031import static com.google.common.base.Preconditions.checkArgument;
32import static com.google.common.base.Preconditions.checkNotNull;
Jian Liedc5db12016-08-23 17:30:19 +090033import static org.onosproject.lisp.msg.types.LispAfiAddress.AfiAddressWriter;
34import static org.onosproject.lisp.msg.protocols.LispEidRecord.EidRecordWriter;
Jian Li20850d32016-08-04 02:15:57 +090035
Jian Li451175e2016-07-19 23:22:20 +090036/**
37 * Default LISP map request message class.
38 */
Jian Lif59c0ad2016-08-02 18:11:30 +090039public final class DefaultLispMapRequest implements LispMapRequest {
40
41 private final long nonce;
Jian Lif59c0ad2016-08-02 18:11:30 +090042 private final LispAfiAddress sourceEid;
43 private final List<LispAfiAddress> itrRlocs;
44 private final List<LispEidRecord> eidRecords;
45 private final boolean authoritative;
46 private final boolean mapDataPresent;
47 private final boolean probe;
48 private final boolean smr;
49 private final boolean pitr;
50 private final boolean smrInvoked;
51
Yoonseon Hanca814bf2016-09-12 11:37:48 -070052 static final RequestWriter WRITER;
53 static {
54 WRITER = new RequestWriter();
55 }
56
Jian Lif59c0ad2016-08-02 18:11:30 +090057 /**
58 * A private constructor that protects object instantiation from external.
59 *
60 * @param nonce nonce
Jian Lif59c0ad2016-08-02 18:11:30 +090061 * @param sourceEid source EID address
62 * @param itrRlocs a collection of ITR RLOCs
63 * @param eidRecords a collection of EID records
64 * @param authoritative authoritative flag
65 * @param mapDataPresent map data present flag
66 * @param probe probe flag
67 * @param smr smr flag
68 * @param pitr pitr flag
69 * @param smrInvoked smrInvoked flag
70 */
Jian Li42b3e432016-08-31 01:05:20 +090071 private DefaultLispMapRequest(long nonce, LispAfiAddress sourceEid,
Jian Lif59c0ad2016-08-02 18:11:30 +090072 List<LispAfiAddress> itrRlocs, List<LispEidRecord> eidRecords,
73 boolean authoritative, boolean mapDataPresent, boolean probe,
74 boolean smr, boolean pitr, boolean smrInvoked) {
75 this.nonce = nonce;
Jian Lif59c0ad2016-08-02 18:11:30 +090076 this.sourceEid = sourceEid;
77 this.itrRlocs = itrRlocs;
78 this.eidRecords = eidRecords;
79 this.authoritative = authoritative;
80 this.mapDataPresent = mapDataPresent;
81 this.probe = probe;
82 this.smr = smr;
83 this.pitr = pitr;
84 this.smrInvoked = smrInvoked;
85 }
86
Jian Li451175e2016-07-19 23:22:20 +090087 @Override
88 public LispType getType() {
Jian Lif59c0ad2016-08-02 18:11:30 +090089 return LispType.LISP_MAP_REQUEST;
Jian Li451175e2016-07-19 23:22:20 +090090 }
91
92 @Override
Yoonseon Hanca814bf2016-09-12 11:37:48 -070093 public void writeTo(ByteBuf byteBuf) throws LispWriterException {
94 WRITER.writeTo(byteBuf, this);
Jian Li451175e2016-07-19 23:22:20 +090095 }
96
97 @Override
98 public Builder createBuilder() {
Jian Li525fded2016-08-04 01:15:33 +090099 return new DefaultRequestBuilder();
Jian Li451175e2016-07-19 23:22:20 +0900100 }
Jian Li719b3bf2016-07-22 00:38:29 +0900101
102 @Override
103 public boolean isAuthoritative() {
Jian Liedc5db12016-08-23 17:30:19 +0900104 return authoritative;
Jian Lif59c0ad2016-08-02 18:11:30 +0900105 }
106
107 @Override
108 public boolean isMapDataPresent() {
Jian Liedc5db12016-08-23 17:30:19 +0900109 return mapDataPresent;
Jian Li719b3bf2016-07-22 00:38:29 +0900110 }
111
112 @Override
113 public boolean isProbe() {
Jian Liedc5db12016-08-23 17:30:19 +0900114 return probe;
Jian Li719b3bf2016-07-22 00:38:29 +0900115 }
116
117 @Override
118 public boolean isSmr() {
Jian Liedc5db12016-08-23 17:30:19 +0900119 return smr;
Jian Li719b3bf2016-07-22 00:38:29 +0900120 }
121
122 @Override
123 public boolean isPitr() {
Jian Liedc5db12016-08-23 17:30:19 +0900124 return pitr;
Jian Li719b3bf2016-07-22 00:38:29 +0900125 }
126
127 @Override
128 public boolean isSmrInvoked() {
Jian Liedc5db12016-08-23 17:30:19 +0900129 return smrInvoked;
Jian Li719b3bf2016-07-22 00:38:29 +0900130 }
131
132 @Override
Jian Li42b3e432016-08-31 01:05:20 +0900133 public int getRecordCount() {
134 return eidRecords.size();
Jian Li719b3bf2016-07-22 00:38:29 +0900135 }
136
137 @Override
138 public long getNonce() {
Jian Liedc5db12016-08-23 17:30:19 +0900139 return nonce;
Jian Li719b3bf2016-07-22 00:38:29 +0900140 }
141
142 @Override
143 public LispAfiAddress getSourceEid() {
Jian Liedc5db12016-08-23 17:30:19 +0900144 return sourceEid;
Jian Li719b3bf2016-07-22 00:38:29 +0900145 }
146
147 @Override
148 public List<LispAfiAddress> getItrRlocs() {
Jian Lif59c0ad2016-08-02 18:11:30 +0900149 return ImmutableList.copyOf(itrRlocs);
Jian Li719b3bf2016-07-22 00:38:29 +0900150 }
151
152 @Override
Jian Li10a09062016-07-26 23:58:50 +0900153 public List<LispEidRecord> getEids() {
Jian Lif59c0ad2016-08-02 18:11:30 +0900154 return ImmutableList.copyOf(eidRecords);
Jian Li719b3bf2016-07-22 00:38:29 +0900155 }
156
Jian Li20850d32016-08-04 02:15:57 +0900157 @Override
158 public String toString() {
159 return toStringHelper(this)
160 .add("type", getType())
161 .add("nonce", nonce)
Jian Li20850d32016-08-04 02:15:57 +0900162 .add("source EID", sourceEid)
163 .add("ITR rlocs", itrRlocs)
164 .add("EID records", eidRecords)
165 .add("authoritative", authoritative)
166 .add("mapDataPresent", mapDataPresent)
167 .add("probe", probe)
168 .add("SMR", smr)
169 .add("Proxy ITR", pitr)
170 .add("SMR Invoked", smrInvoked).toString();
171 }
172
173 @Override
174 public boolean equals(Object o) {
175 if (this == o) {
176 return true;
177 }
178 if (o == null || getClass() != o.getClass()) {
179 return false;
180 }
181 DefaultLispMapRequest that = (DefaultLispMapRequest) o;
182 return Objects.equal(nonce, that.nonce) &&
Jian Li20850d32016-08-04 02:15:57 +0900183 Objects.equal(sourceEid, that.sourceEid) &&
Jian Li20850d32016-08-04 02:15:57 +0900184 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() {
Jian Li42b3e432016-08-31 01:05:20 +0900194 return Objects.hashCode(nonce, sourceEid, authoritative,
Jian Lie4ba2a42016-08-29 20:24:15 +0900195 mapDataPresent, probe, smr, pitr, smrInvoked);
Jian Li20850d32016-08-04 02:15:57 +0900196 }
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;
Jian Lif59c0ad2016-08-02 18:11:30 +0900201 private LispAfiAddress sourceEid;
202 private List<LispAfiAddress> itrRlocs = Lists.newArrayList();
203 private List<LispEidRecord> eidRecords = Lists.newArrayList();
204 private boolean authoritative;
205 private boolean mapDataPresent;
206 private boolean probe;
207 private boolean smr;
208 private boolean pitr;
209 private boolean smrInvoked;
Jian Li719b3bf2016-07-22 00:38:29 +0900210
211 @Override
212 public LispType getType() {
Jian Lif59c0ad2016-08-02 18:11:30 +0900213 return LispType.LISP_MAP_REQUEST;
Jian Li719b3bf2016-07-22 00:38:29 +0900214 }
215
216 @Override
Jian Lif59c0ad2016-08-02 18:11:30 +0900217 public RequestBuilder withIsAuthoritative(boolean authoritative) {
218 this.authoritative = authoritative;
219 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900220 }
221
222 @Override
Jian Lif59c0ad2016-08-02 18:11:30 +0900223 public RequestBuilder withIsProbe(boolean probe) {
224 this.probe = probe;
225 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900226 }
227
228 @Override
Jian Lif59c0ad2016-08-02 18:11:30 +0900229 public RequestBuilder withIsMapDataPresent(boolean mapDataPresent) {
230 this.mapDataPresent = mapDataPresent;
231 return this;
232 }
233
Jian Lif59c0ad2016-08-02 18:11:30 +0900234 @Override
235 public RequestBuilder withIsSmr(boolean smr) {
236 this.smr = smr;
237 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900238 }
239
240 @Override
Jian Lif59c0ad2016-08-02 18:11:30 +0900241 public RequestBuilder withIsPitr(boolean pitr) {
242 this.pitr = pitr;
243 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900244 }
245
246 @Override
Jian Lif59c0ad2016-08-02 18:11:30 +0900247 public RequestBuilder withIsSmrInvoked(boolean smrInvoked) {
248 this.smrInvoked = smrInvoked;
249 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900250 }
251
252 @Override
Jian Li719b3bf2016-07-22 00:38:29 +0900253 public RequestBuilder withNonce(long nonce) {
Jian Lif59c0ad2016-08-02 18:11:30 +0900254 this.nonce = nonce;
255 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900256 }
257
258 @Override
Jian Lif59c0ad2016-08-02 18:11:30 +0900259 public RequestBuilder withSourceEid(LispAfiAddress sourceEid) {
260 this.sourceEid = sourceEid;
261 return this;
262 }
263
264 @Override
Jian Li47671902016-08-11 01:18:18 +0900265 public RequestBuilder withItrRlocs(List<LispAfiAddress> itrRlocs) {
Jian Lie4ba2a42016-08-29 20:24:15 +0900266 if (itrRlocs != null) {
267 this.itrRlocs = ImmutableList.copyOf(itrRlocs);
Jian Lie4ba2a42016-08-29 20:24:15 +0900268 }
Jian Lif59c0ad2016-08-02 18:11:30 +0900269 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900270 }
271
272 @Override
Jian Li47671902016-08-11 01:18:18 +0900273 public RequestBuilder withEidRecords(List<LispEidRecord> records) {
Jian Lie4ba2a42016-08-29 20:24:15 +0900274 if (records != null) {
275 this.eidRecords = ImmutableList.copyOf(records);
Jian Lie4ba2a42016-08-29 20:24:15 +0900276 }
Jian Lif59c0ad2016-08-02 18:11:30 +0900277 return this;
278 }
279
280 @Override
Jian Li525fded2016-08-04 01:15:33 +0900281 public LispMapRequest build() {
Jian Lie4ba2a42016-08-29 20:24:15 +0900282
283 checkNotNull(sourceEid, "Must have a source EID");
284 checkArgument((itrRlocs != null) && (itrRlocs.size() > 0), "Must have an ITR RLOC entry");
285
Jian Li42b3e432016-08-31 01:05:20 +0900286 return new DefaultLispMapRequest(nonce, sourceEid, itrRlocs, eidRecords,
287 authoritative, mapDataPresent, probe, smr, pitr, smrInvoked);
Jian Li719b3bf2016-07-22 00:38:29 +0900288 }
289 }
Jian Li26069e22016-08-10 22:00:52 +0900290
291 /**
Jian Liedc5db12016-08-23 17:30:19 +0900292 * A LISP message reader for MapRequest message.
Jian Li26069e22016-08-10 22:00:52 +0900293 */
Jian Liedc5db12016-08-23 17:30:19 +0900294 public static final class RequestReader implements LispMessageReader<LispMapRequest> {
Jian Li26069e22016-08-10 22:00:52 +0900295
Jian Li47671902016-08-11 01:18:18 +0900296 private static final int AUTHORITATIVE_INDEX = 3;
297 private static final int MAP_DATA_PRESENT_INDEX = 2;
298 private static final int PROBE_INDEX = 1;
299 private static final int SMR_INDEX = 0;
300 private static final int PITR_INDEX = 7;
301 private static final int SMR_INVOKED_INDEX = 6;
302
Jian Li26069e22016-08-10 22:00:52 +0900303 @Override
Jian Lia7b394d2016-08-21 23:11:46 +0900304 public LispMapRequest readFrom(ByteBuf byteBuf) throws LispParseError, LispReaderException {
Jian Li47671902016-08-11 01:18:18 +0900305
306 if (byteBuf.readerIndex() != 0) {
307 return null;
308 }
309
310 byte typeWithFlags = byteBuf.readByte();
311
312 // authoritative -> 1 bit
313 boolean authoritative = ByteOperator.getBit(typeWithFlags, AUTHORITATIVE_INDEX);
314
315 // mapDataPresent -> 1 bit
316 boolean mapDataPresent = ByteOperator.getBit(typeWithFlags, MAP_DATA_PRESENT_INDEX);
317
318 // probe -> 1 bit
319 boolean probe = ByteOperator.getBit(typeWithFlags, PROBE_INDEX);
320
321 // smr -> 1 bit
322 boolean smr = ByteOperator.getBit(typeWithFlags, SMR_INDEX);
323
324 byte reservedWithFlags = byteBuf.readByte();
325
326 // pitr -> 1 bit
327 boolean pitr = ByteOperator.getBit(reservedWithFlags, PITR_INDEX);
328
329 // smrInvoked -> 1 bit
330 boolean smrInvoked = ByteOperator.getBit(reservedWithFlags, SMR_INVOKED_INDEX);
331
332 // let's skip reserved field, only obtains ITR counter value
333 // assume that first 3 bits are all set as 0,
334 // remain 5 bits represent Itr Rloc Counter (IRC)
Jian Lie4ba2a42016-08-29 20:24:15 +0900335 int irc = byteBuf.readUnsignedByte();
Jian Li47671902016-08-11 01:18:18 +0900336
337 // record count -> 8 bits
Jian Lie4ba2a42016-08-29 20:24:15 +0900338 int recordCount = byteBuf.readUnsignedByte();
Jian Li47671902016-08-11 01:18:18 +0900339
340 // nonce -> 64 bits
341 long nonce = byteBuf.readLong();
342
Jian Lia7b394d2016-08-21 23:11:46 +0900343 LispAfiAddress sourceEid = new LispAfiAddress.AfiAddressReader().readFrom(byteBuf);
Jian Li47671902016-08-11 01:18:18 +0900344
Jian Lia7b394d2016-08-21 23:11:46 +0900345 // deserialize a collection of RLOC addresses
346 List<LispAfiAddress> itrRlocs = Lists.newArrayList();
347 for (int i = 0; i < irc; i++) {
348 itrRlocs.add(new LispAfiAddress.AfiAddressReader().readFrom(byteBuf));
349 }
Jian Li47671902016-08-11 01:18:18 +0900350
Jian Lia7b394d2016-08-21 23:11:46 +0900351 // deserialize a collection of EID records
352 List<LispEidRecord> eidRecords = Lists.newArrayList();
353 for (int i = 0; i < recordCount; i++) {
354 eidRecords.add(new LispEidRecord.EidRecordReader().readFrom(byteBuf));
355 }
Jian Li47671902016-08-11 01:18:18 +0900356
357 return new DefaultRequestBuilder()
358 .withIsAuthoritative(authoritative)
359 .withIsMapDataPresent(mapDataPresent)
360 .withIsProbe(probe)
361 .withIsSmr(smr)
362 .withIsPitr(pitr)
363 .withIsSmrInvoked(smrInvoked)
364 .withNonce(nonce)
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
Jian Liedc5db12016-08-23 17:30:19 +0900377 private static final int REQUEST_SHIFT_BIT = 4;
378
379 private static final int AUTHORITATIVE_SHIFT_BIT = 3;
380 private static final int MAP_DATA_PRESENT_SHIFT_BIT = 2;
381 private static final int PROBE_SHIFT_BIT = 1;
382
383 private static final int PITR_SHIFT_BIT = 7;
384 private static final int SMR_INVOKED_SHIFT_BIT = 6;
385
386 private static final int ENABLE_BIT = 1;
387 private static final int DISABLE_BIT = 0;
388
Jian Liedc5db12016-08-23 17:30:19 +0900389 @Override
390 public void writeTo(ByteBuf byteBuf, LispMapRequest message) throws LispWriterException {
391
392 // specify LISP message type
Jian Licbc57e32016-09-14 09:06:54 +0900393 byte msgType = (byte) (LispType.LISP_MAP_REQUEST.getTypeCode() << REQUEST_SHIFT_BIT);
Jian Liedc5db12016-08-23 17:30:19 +0900394
395 // authoritative flag
396 byte authoritative = DISABLE_BIT;
397 if (message.isAuthoritative()) {
398 authoritative = (byte) (ENABLE_BIT << AUTHORITATIVE_SHIFT_BIT);
399 }
400
401 // map data present flag
402 byte mapDataPresent = DISABLE_BIT;
403 if (message.isMapDataPresent()) {
404 mapDataPresent = (byte) (ENABLE_BIT << MAP_DATA_PRESENT_SHIFT_BIT);
405 }
406
407 // probe flag
408 byte probe = DISABLE_BIT;
409 if (message.isProbe()) {
410 probe = (byte) (ENABLE_BIT << PROBE_SHIFT_BIT);
411 }
412
413 // SMR flag
414 byte smr = DISABLE_BIT;
415 if (message.isSmr()) {
416 smr = (byte) ENABLE_BIT;
417 }
418
419 byteBuf.writeByte((byte) (msgType + authoritative + mapDataPresent + probe + smr));
420
421 // PITR flag bit
422 byte pitr = DISABLE_BIT;
423 if (message.isPitr()) {
424 pitr = (byte) (ENABLE_BIT << PITR_SHIFT_BIT);
425 }
426
427 // SMR invoked flag bit
428 byte smrInvoked = DISABLE_BIT;
429 if (message.isSmrInvoked()) {
430 smrInvoked = (byte) (ENABLE_BIT << SMR_INVOKED_SHIFT_BIT);
431 }
432
433 byteBuf.writeByte((byte) (pitr + smrInvoked));
434
Jian Lie4ba2a42016-08-29 20:24:15 +0900435 // ITR Rloc count
436 byteBuf.writeByte((byte) message.getItrRlocs().size());
Jian Liedc5db12016-08-23 17:30:19 +0900437
438 // record count
Jian Li42b3e432016-08-31 01:05:20 +0900439 byteBuf.writeByte(message.getEids().size());
Jian Liedc5db12016-08-23 17:30:19 +0900440
441 // nonce
442 byteBuf.writeLong(message.getNonce());
443
444 // Source EID AFI with Source EID address
445 AfiAddressWriter afiAddressWriter = new AfiAddressWriter();
446 afiAddressWriter.writeTo(byteBuf, message.getSourceEid());
447
448 // ITR RLOCs
449 List<LispAfiAddress> rlocs = message.getItrRlocs();
450 for (int i = 0; i < rlocs.size(); i++) {
451 afiAddressWriter.writeTo(byteBuf, rlocs.get(i));
452 }
453
454 // EID records
455 EidRecordWriter recordWriter = new EidRecordWriter();
456 List<LispEidRecord> records = message.getEids();
457
458 for (int i = 0; i < records.size(); i++) {
459 recordWriter.writeTo(byteBuf, records.get(i));
460 }
461
462 // TODO: handle Map-Reply record
463 }
464 }
Jian Li451175e2016-07-19 23:22:20 +0900465}