blob: 9c6ff92adffe089bf95558e9a821ee05f079b55a [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 Li719b3bf2016-07-22 00:38:29 +090025import org.onosproject.lisp.msg.types.LispAfiAddress;
26
27import java.util.List;
Jian Li451175e2016-07-19 23:22:20 +090028
Jian Li20850d32016-08-04 02:15:57 +090029import static com.google.common.base.MoreObjects.toStringHelper;
30
Jian Li451175e2016-07-19 23:22:20 +090031/**
32 * Default LISP map request message class.
33 */
Jian Lif59c0ad2016-08-02 18:11:30 +090034public final class DefaultLispMapRequest implements LispMapRequest {
35
36 private final long nonce;
37 private final byte recordCount;
38 private final LispAfiAddress sourceEid;
39 private final List<LispAfiAddress> itrRlocs;
40 private final List<LispEidRecord> eidRecords;
41 private final boolean authoritative;
42 private final boolean mapDataPresent;
43 private final boolean probe;
44 private final boolean smr;
45 private final boolean pitr;
46 private final boolean smrInvoked;
47
48 /**
49 * A private constructor that protects object instantiation from external.
50 *
51 * @param nonce nonce
52 * @param recordCount record count number
53 * @param sourceEid source EID address
54 * @param itrRlocs a collection of ITR RLOCs
55 * @param eidRecords a collection of EID records
56 * @param authoritative authoritative flag
57 * @param mapDataPresent map data present flag
58 * @param probe probe flag
59 * @param smr smr flag
60 * @param pitr pitr flag
61 * @param smrInvoked smrInvoked flag
62 */
63 private DefaultLispMapRequest(long nonce, byte recordCount, LispAfiAddress sourceEid,
64 List<LispAfiAddress> itrRlocs, List<LispEidRecord> eidRecords,
65 boolean authoritative, boolean mapDataPresent, boolean probe,
66 boolean smr, boolean pitr, boolean smrInvoked) {
67 this.nonce = nonce;
68 this.recordCount = recordCount;
69 this.sourceEid = sourceEid;
70 this.itrRlocs = itrRlocs;
71 this.eidRecords = eidRecords;
72 this.authoritative = authoritative;
73 this.mapDataPresent = mapDataPresent;
74 this.probe = probe;
75 this.smr = smr;
76 this.pitr = pitr;
77 this.smrInvoked = smrInvoked;
78 }
79
Jian Li451175e2016-07-19 23:22:20 +090080 @Override
81 public LispType getType() {
Jian Lif59c0ad2016-08-02 18:11:30 +090082 return LispType.LISP_MAP_REQUEST;
Jian Li451175e2016-07-19 23:22:20 +090083 }
84
85 @Override
86 public void writeTo(ByteBuf byteBuf) {
Jian Lif59c0ad2016-08-02 18:11:30 +090087 // TODO: serialize LispMapRequest message
Jian Li451175e2016-07-19 23:22:20 +090088 }
89
90 @Override
91 public Builder createBuilder() {
Jian Li525fded2016-08-04 01:15:33 +090092 return new DefaultRequestBuilder();
Jian Li451175e2016-07-19 23:22:20 +090093 }
Jian Li719b3bf2016-07-22 00:38:29 +090094
95 @Override
96 public boolean isAuthoritative() {
Jian Lif59c0ad2016-08-02 18:11:30 +090097 return this.authoritative;
98 }
99
100 @Override
101 public boolean isMapDataPresent() {
102 return this.mapDataPresent;
Jian Li719b3bf2016-07-22 00:38:29 +0900103 }
104
105 @Override
106 public boolean isProbe() {
Jian Lif59c0ad2016-08-02 18:11:30 +0900107 return this.probe;
Jian Li719b3bf2016-07-22 00:38:29 +0900108 }
109
110 @Override
111 public boolean isSmr() {
Jian Lif59c0ad2016-08-02 18:11:30 +0900112 return this.smr;
Jian Li719b3bf2016-07-22 00:38:29 +0900113 }
114
115 @Override
116 public boolean isPitr() {
Jian Lif59c0ad2016-08-02 18:11:30 +0900117 return this.pitr;
Jian Li719b3bf2016-07-22 00:38:29 +0900118 }
119
120 @Override
121 public boolean isSmrInvoked() {
Jian Lif59c0ad2016-08-02 18:11:30 +0900122 return this.smrInvoked;
Jian Li719b3bf2016-07-22 00:38:29 +0900123 }
124
125 @Override
126 public byte getRecordCount() {
Jian Lif59c0ad2016-08-02 18:11:30 +0900127 return this.recordCount;
Jian Li719b3bf2016-07-22 00:38:29 +0900128 }
129
130 @Override
131 public long getNonce() {
Jian Lif59c0ad2016-08-02 18:11:30 +0900132 return this.nonce;
Jian Li719b3bf2016-07-22 00:38:29 +0900133 }
134
135 @Override
136 public LispAfiAddress getSourceEid() {
Jian Lif59c0ad2016-08-02 18:11:30 +0900137 return this.sourceEid;
Jian Li719b3bf2016-07-22 00:38:29 +0900138 }
139
140 @Override
141 public List<LispAfiAddress> getItrRlocs() {
Jian Lif59c0ad2016-08-02 18:11:30 +0900142 return ImmutableList.copyOf(itrRlocs);
Jian Li719b3bf2016-07-22 00:38:29 +0900143 }
144
145 @Override
Jian Li10a09062016-07-26 23:58:50 +0900146 public List<LispEidRecord> getEids() {
Jian Lif59c0ad2016-08-02 18:11:30 +0900147 return ImmutableList.copyOf(eidRecords);
Jian Li719b3bf2016-07-22 00:38:29 +0900148 }
149
Jian Li20850d32016-08-04 02:15:57 +0900150 @Override
151 public String toString() {
152 return toStringHelper(this)
153 .add("type", getType())
154 .add("nonce", nonce)
155 .add("recordCount", recordCount)
156 .add("source EID", sourceEid)
157 .add("ITR rlocs", itrRlocs)
158 .add("EID records", eidRecords)
159 .add("authoritative", authoritative)
160 .add("mapDataPresent", mapDataPresent)
161 .add("probe", probe)
162 .add("SMR", smr)
163 .add("Proxy ITR", pitr)
164 .add("SMR Invoked", smrInvoked).toString();
165 }
166
167 @Override
168 public boolean equals(Object o) {
169 if (this == o) {
170 return true;
171 }
172 if (o == null || getClass() != o.getClass()) {
173 return false;
174 }
175 DefaultLispMapRequest that = (DefaultLispMapRequest) o;
176 return Objects.equal(nonce, that.nonce) &&
177 Objects.equal(recordCount, that.recordCount) &&
178 Objects.equal(sourceEid, that.sourceEid) &&
179 Objects.equal(itrRlocs, that.itrRlocs) &&
180 Objects.equal(eidRecords, that.eidRecords) &&
181 Objects.equal(authoritative, that.authoritative) &&
182 Objects.equal(mapDataPresent, that.mapDataPresent) &&
183 Objects.equal(probe, that.probe) &&
184 Objects.equal(smr, that.smr) &&
185 Objects.equal(pitr, that.pitr) &&
186 Objects.equal(smrInvoked, that.smrInvoked);
187 }
188
189 @Override
190 public int hashCode() {
191 return Objects.hashCode(nonce, recordCount, sourceEid, itrRlocs, eidRecords,
192 authoritative, mapDataPresent, probe, smr, pitr, smrInvoked);
193 }
194
Jian Li719b3bf2016-07-22 00:38:29 +0900195 public static final class DefaultRequestBuilder implements RequestBuilder {
196
Jian Lif59c0ad2016-08-02 18:11:30 +0900197 private long nonce;
198 private byte recordCount;
199 private LispAfiAddress sourceEid;
200 private List<LispAfiAddress> itrRlocs = Lists.newArrayList();
201 private List<LispEidRecord> eidRecords = Lists.newArrayList();
202 private boolean authoritative;
203 private boolean mapDataPresent;
204 private boolean probe;
205 private boolean smr;
206 private boolean pitr;
207 private boolean smrInvoked;
Jian Li719b3bf2016-07-22 00:38:29 +0900208
209 @Override
210 public LispType getType() {
Jian Lif59c0ad2016-08-02 18:11:30 +0900211 return LispType.LISP_MAP_REQUEST;
Jian Li719b3bf2016-07-22 00:38:29 +0900212 }
213
214 @Override
Jian Lif59c0ad2016-08-02 18:11:30 +0900215 public RequestBuilder withIsAuthoritative(boolean authoritative) {
216 this.authoritative = authoritative;
217 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900218 }
219
220 @Override
Jian Lif59c0ad2016-08-02 18:11:30 +0900221 public RequestBuilder withIsProbe(boolean probe) {
222 this.probe = probe;
223 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900224 }
225
226 @Override
Jian Lif59c0ad2016-08-02 18:11:30 +0900227 public RequestBuilder withIsMapDataPresent(boolean mapDataPresent) {
228 this.mapDataPresent = mapDataPresent;
229 return this;
230 }
231
Jian Lif59c0ad2016-08-02 18:11:30 +0900232 @Override
233 public RequestBuilder withIsSmr(boolean smr) {
234 this.smr = smr;
235 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900236 }
237
238 @Override
Jian Lif59c0ad2016-08-02 18:11:30 +0900239 public RequestBuilder withIsPitr(boolean pitr) {
240 this.pitr = pitr;
241 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900242 }
243
244 @Override
Jian Lif59c0ad2016-08-02 18:11:30 +0900245 public RequestBuilder withIsSmrInvoked(boolean smrInvoked) {
246 this.smrInvoked = smrInvoked;
247 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900248 }
249
250 @Override
251 public RequestBuilder withRecordCount(byte recordCount) {
Jian Lif59c0ad2016-08-02 18:11:30 +0900252 this.recordCount = recordCount;
253 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900254 }
255
256 @Override
257 public RequestBuilder withNonce(long nonce) {
Jian Lif59c0ad2016-08-02 18:11:30 +0900258 this.nonce = nonce;
259 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900260 }
261
262 @Override
Jian Lif59c0ad2016-08-02 18:11:30 +0900263 public RequestBuilder withSourceEid(LispAfiAddress sourceEid) {
264 this.sourceEid = sourceEid;
265 return this;
266 }
267
268 @Override
Jian Li47671902016-08-11 01:18:18 +0900269 public RequestBuilder withItrRlocs(List<LispAfiAddress> itrRlocs) {
270 this.itrRlocs = ImmutableList.copyOf(itrRlocs);
Jian Lif59c0ad2016-08-02 18:11:30 +0900271 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900272 }
273
274 @Override
Jian Li47671902016-08-11 01:18:18 +0900275 public RequestBuilder withEidRecords(List<LispEidRecord> records) {
276 this.eidRecords = ImmutableList.copyOf(records);
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 Lif59c0ad2016-08-02 18:11:30 +0900282 return new DefaultLispMapRequest(nonce, recordCount, sourceEid, itrRlocs,
283 eidRecords, authoritative, mapDataPresent, probe, smr, pitr, smrInvoked);
Jian Li719b3bf2016-07-22 00:38:29 +0900284 }
285 }
Jian Li26069e22016-08-10 22:00:52 +0900286
287 /**
288 * A private LISP message reader for MapRequest message.
289 */
290 private static class RequestReader implements LispMessageReader<LispMapRequest> {
291
Jian Li47671902016-08-11 01:18:18 +0900292 private static final int AUTHORITATIVE_INDEX = 3;
293 private static final int MAP_DATA_PRESENT_INDEX = 2;
294 private static final int PROBE_INDEX = 1;
295 private static final int SMR_INDEX = 0;
296 private static final int PITR_INDEX = 7;
297 private static final int SMR_INVOKED_INDEX = 6;
298
Jian Li26069e22016-08-10 22:00:52 +0900299 @Override
Jian Lia7b394d2016-08-21 23:11:46 +0900300 public LispMapRequest readFrom(ByteBuf byteBuf) throws LispParseError, LispReaderException {
Jian Li47671902016-08-11 01:18:18 +0900301
302 if (byteBuf.readerIndex() != 0) {
303 return null;
304 }
305
306 byte typeWithFlags = byteBuf.readByte();
307
308 // authoritative -> 1 bit
309 boolean authoritative = ByteOperator.getBit(typeWithFlags, AUTHORITATIVE_INDEX);
310
311 // mapDataPresent -> 1 bit
312 boolean mapDataPresent = ByteOperator.getBit(typeWithFlags, MAP_DATA_PRESENT_INDEX);
313
314 // probe -> 1 bit
315 boolean probe = ByteOperator.getBit(typeWithFlags, PROBE_INDEX);
316
317 // smr -> 1 bit
318 boolean smr = ByteOperator.getBit(typeWithFlags, SMR_INDEX);
319
320 byte reservedWithFlags = byteBuf.readByte();
321
322 // pitr -> 1 bit
323 boolean pitr = ByteOperator.getBit(reservedWithFlags, PITR_INDEX);
324
325 // smrInvoked -> 1 bit
326 boolean smrInvoked = ByteOperator.getBit(reservedWithFlags, SMR_INVOKED_INDEX);
327
328 // let's skip reserved field, only obtains ITR counter value
329 // assume that first 3 bits are all set as 0,
330 // remain 5 bits represent Itr Rloc Counter (IRC)
331 int irc = byteBuf.readUnsignedShort();
332
333 // record count -> 8 bits
334 int recordCount = byteBuf.readUnsignedShort();
335
336 // nonce -> 64 bits
337 long nonce = byteBuf.readLong();
338
Jian Lia7b394d2016-08-21 23:11:46 +0900339 LispAfiAddress sourceEid = new LispAfiAddress.AfiAddressReader().readFrom(byteBuf);
Jian Li47671902016-08-11 01:18:18 +0900340
Jian Lia7b394d2016-08-21 23:11:46 +0900341 // deserialize a collection of RLOC addresses
342 List<LispAfiAddress> itrRlocs = Lists.newArrayList();
343 for (int i = 0; i < irc; i++) {
344 itrRlocs.add(new LispAfiAddress.AfiAddressReader().readFrom(byteBuf));
345 }
Jian Li47671902016-08-11 01:18:18 +0900346
Jian Lia7b394d2016-08-21 23:11:46 +0900347 // deserialize a collection of EID records
348 List<LispEidRecord> eidRecords = Lists.newArrayList();
349 for (int i = 0; i < recordCount; i++) {
350 eidRecords.add(new LispEidRecord.EidRecordReader().readFrom(byteBuf));
351 }
Jian Li47671902016-08-11 01:18:18 +0900352
353 return new DefaultRequestBuilder()
354 .withIsAuthoritative(authoritative)
355 .withIsMapDataPresent(mapDataPresent)
356 .withIsProbe(probe)
357 .withIsSmr(smr)
358 .withIsPitr(pitr)
359 .withIsSmrInvoked(smrInvoked)
360 .withNonce(nonce)
361 .withRecordCount((byte) recordCount)
Jian Lia7b394d2016-08-21 23:11:46 +0900362 .withSourceEid(sourceEid)
363 .withEidRecords(eidRecords)
364 .withItrRlocs(itrRlocs)
Jian Li47671902016-08-11 01:18:18 +0900365 .build();
Jian Li26069e22016-08-10 22:00:52 +0900366 }
367 }
Jian Li451175e2016-07-19 23:22:20 +0900368}