blob: c681e06b1687a974d73eb73cc10a617b467b345d [file] [log] [blame]
Jian Li10a09062016-07-26 23:58:50 +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 Li18f3bce2016-08-04 17:36:41 +090018import com.google.common.base.Objects;
Jian Li47671902016-08-11 01:18:18 +090019import com.google.common.collect.ImmutableList;
20import com.google.common.collect.Lists;
Jian Li26069e22016-08-10 22:00:52 +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 Li10a09062016-07-26 23:58:50 +090024import org.onosproject.lisp.msg.types.LispAfiAddress;
25
Jian Li47671902016-08-11 01:18:18 +090026import java.util.List;
27
Jian Li18f3bce2016-08-04 17:36:41 +090028import static com.google.common.base.MoreObjects.toStringHelper;
29
Jian Li10a09062016-07-26 23:58:50 +090030/**
31 * Default implementation of LispMapRecord.
32 */
Jian Li631e62a2016-08-03 22:42:00 +090033public final class DefaultLispMapRecord implements LispMapRecord {
Jian Li10a09062016-07-26 23:58:50 +090034
Jian Li631e62a2016-08-03 22:42:00 +090035 private final int recordTtl;
36 private final int locatorCount;
37 private final byte maskLength;
38 private final LispMapReplyAction action;
39 private final boolean authoritative;
40 private final short mapVersionNumber;
41 private final LispAfiAddress eidPrefixAfi;
Jian Li47671902016-08-11 01:18:18 +090042 private final List<LispLocatorRecord> locatorRecords;
Jian Li10a09062016-07-26 23:58:50 +090043
Jian Li631e62a2016-08-03 22:42:00 +090044 /**
45 * A private constructor that protects object instantiation from external.
46 *
47 * @param recordTtl record time-to-live value
48 * @param locatorCount locator's count number
49 * @param maskLength mask length
50 * @param action lisp map reply action
51 * @param authoritative authoritative flag
52 * @param mapVersionNumber map version number
53 * @param eidPrefixAfi EID prefix AFI address
54 */
55 private DefaultLispMapRecord(int recordTtl, int locatorCount, byte maskLength,
56 LispMapReplyAction action, boolean authoritative,
Jian Li47671902016-08-11 01:18:18 +090057 short mapVersionNumber, LispAfiAddress eidPrefixAfi,
58 List<LispLocatorRecord> locatorRecords) {
Jian Li631e62a2016-08-03 22:42:00 +090059 this.recordTtl = recordTtl;
60 this.locatorCount = locatorCount;
61 this.maskLength = maskLength;
62 this.action = action;
63 this.authoritative = authoritative;
64 this.mapVersionNumber = mapVersionNumber;
65 this.eidPrefixAfi = eidPrefixAfi;
Jian Li47671902016-08-11 01:18:18 +090066 this.locatorRecords = locatorRecords;
Jian Li631e62a2016-08-03 22:42:00 +090067 }
68
69 @Override
Jian Li10a09062016-07-26 23:58:50 +090070 public int getRecordTtl() {
71 return recordTtl;
72 }
73
Jian Li631e62a2016-08-03 22:42:00 +090074 @Override
Jian Li10a09062016-07-26 23:58:50 +090075 public int getLocatorCount() {
76 return locatorCount;
77 }
78
Jian Li631e62a2016-08-03 22:42:00 +090079 @Override
Jian Li10a09062016-07-26 23:58:50 +090080 public byte getMaskLength() {
81 return maskLength;
82 }
83
Jian Li631e62a2016-08-03 22:42:00 +090084 @Override
Jian Li10a09062016-07-26 23:58:50 +090085 public LispMapReplyAction getAction() {
86 return action;
87 }
88
Jian Li631e62a2016-08-03 22:42:00 +090089 @Override
Jian Li10a09062016-07-26 23:58:50 +090090 public boolean isAuthoritative() {
91 return authoritative;
92 }
93
Jian Li631e62a2016-08-03 22:42:00 +090094 @Override
Jian Li10a09062016-07-26 23:58:50 +090095 public short getMapVersionNumber() {
96 return mapVersionNumber;
97 }
98
Jian Li631e62a2016-08-03 22:42:00 +090099 @Override
Jian Li10a09062016-07-26 23:58:50 +0900100 public LispAfiAddress getEidPrefixAfi() {
101 return eidPrefixAfi;
102 }
103
Jian Li18f3bce2016-08-04 17:36:41 +0900104 @Override
Jian Li47671902016-08-11 01:18:18 +0900105 public List<LispLocatorRecord> getLocators() {
106 return ImmutableList.copyOf(locatorRecords);
107 }
108
109 @Override
110 public void writeTo(ByteBuf byteBuf) {
111
112 }
113
114 @Override
Jian Li18f3bce2016-08-04 17:36:41 +0900115 public String toString() {
116 return toStringHelper(this)
117 .add("record TTL", recordTtl)
118 .add("locatorCount", locatorCount)
119 .add("maskLength", maskLength)
120 .add("action", action)
121 .add("authoritative", authoritative)
122 .add("mapVersionNumber", mapVersionNumber)
Jian Li47671902016-08-11 01:18:18 +0900123 .add("EID prefix AFI address", eidPrefixAfi)
124 .add("locator records", locatorRecords).toString();
125
Jian Li18f3bce2016-08-04 17:36:41 +0900126 }
127
128 @Override
129 public boolean equals(Object o) {
130 if (this == o) {
131 return true;
132 }
133 if (o == null || getClass() != o.getClass()) {
134 return false;
135 }
136 DefaultLispMapRecord that = (DefaultLispMapRecord) o;
137 return Objects.equal(recordTtl, that.recordTtl) &&
138 Objects.equal(locatorCount, that.locatorCount) &&
139 Objects.equal(maskLength, that.maskLength) &&
140 Objects.equal(action, that.action) &&
141 Objects.equal(authoritative, that.authoritative) &&
142 Objects.equal(mapVersionNumber, that.mapVersionNumber) &&
Jian Li47671902016-08-11 01:18:18 +0900143 Objects.equal(eidPrefixAfi, that.eidPrefixAfi) &&
144 Objects.equal(locatorRecords, that.locatorRecords);
Jian Li18f3bce2016-08-04 17:36:41 +0900145 }
146
147 @Override
148 public int hashCode() {
149 return Objects.hashCode(recordTtl, locatorCount, maskLength, action,
Jian Li47671902016-08-11 01:18:18 +0900150 authoritative, mapVersionNumber, eidPrefixAfi, locatorRecords);
Jian Li18f3bce2016-08-04 17:36:41 +0900151 }
152
Jian Li10a09062016-07-26 23:58:50 +0900153 public static final class DefaultMapRecordBuilder implements MapRecordBuilder {
154
Jian Li631e62a2016-08-03 22:42:00 +0900155 private int recordTtl;
156 private int locatorCount;
157 private byte maskLength;
158 private LispMapReplyAction action;
159 private boolean authoritative;
160 private short mapVersionNumber;
161 private LispAfiAddress eidPrefixAfi;
Jian Li47671902016-08-11 01:18:18 +0900162 private List<LispLocatorRecord> locatorRecords;
Jian Li631e62a2016-08-03 22:42:00 +0900163
Jian Li10a09062016-07-26 23:58:50 +0900164 @Override
165 public MapRecordBuilder withRecordTtl(int recordTtl) {
Jian Li631e62a2016-08-03 22:42:00 +0900166 this.recordTtl = recordTtl;
167 return this;
Jian Li10a09062016-07-26 23:58:50 +0900168 }
169
170 @Override
171 public MapRecordBuilder withLocatorCount(int locatorCount) {
Jian Li631e62a2016-08-03 22:42:00 +0900172 this.locatorCount = locatorCount;
173 return this;
Jian Li10a09062016-07-26 23:58:50 +0900174 }
175
176 @Override
177 public MapRecordBuilder withMaskLength(byte maskLength) {
Jian Li631e62a2016-08-03 22:42:00 +0900178 this.maskLength = maskLength;
179 return this;
Jian Li10a09062016-07-26 23:58:50 +0900180 }
181
182 @Override
183 public MapRecordBuilder withAction(LispMapReplyAction action) {
Jian Li631e62a2016-08-03 22:42:00 +0900184 this.action = action;
185 return this;
Jian Li10a09062016-07-26 23:58:50 +0900186 }
187
188 @Override
189 public MapRecordBuilder withAuthoritative(boolean authoritative) {
Jian Li631e62a2016-08-03 22:42:00 +0900190 this.authoritative = authoritative;
191 return this;
Jian Li10a09062016-07-26 23:58:50 +0900192 }
193
194 @Override
195 public MapRecordBuilder withMapVersionNumber(short mapVersionNumber) {
Jian Li631e62a2016-08-03 22:42:00 +0900196 this.mapVersionNumber = mapVersionNumber;
197 return this;
Jian Li10a09062016-07-26 23:58:50 +0900198 }
199
200 @Override
201 public MapRecordBuilder withEidPrefixAfi(LispAfiAddress prefix) {
Jian Li631e62a2016-08-03 22:42:00 +0900202 this.eidPrefixAfi = prefix;
203 return this;
204 }
205
206 @Override
Jian Li47671902016-08-11 01:18:18 +0900207 public MapRecordBuilder withLocators(List<LispLocatorRecord> records) {
208 this.locatorRecords = ImmutableList.copyOf(records);
209 return this;
210 }
211
212 @Override
Jian Li631e62a2016-08-03 22:42:00 +0900213 public LispMapRecord build() {
214 return new DefaultLispMapRecord(recordTtl, locatorCount, maskLength,
Jian Li47671902016-08-11 01:18:18 +0900215 action, authoritative, mapVersionNumber, eidPrefixAfi, locatorRecords);
Jian Li10a09062016-07-26 23:58:50 +0900216 }
217 }
Jian Li26069e22016-08-10 22:00:52 +0900218
219 /**
Jian Li47671902016-08-11 01:18:18 +0900220 * A LISP message reader for MapRecord portion.
Jian Li26069e22016-08-10 22:00:52 +0900221 */
Jian Li47671902016-08-11 01:18:18 +0900222 public static final class MapRecordReader implements LispMessageReader<LispMapRecord> {
223
224 private static final int AUTHORITATIVE_INDEX = 4;
225 private static final int RESERVED_SKIP_LENGTH = 1;
Jian Li26069e22016-08-10 22:00:52 +0900226
227 @Override
228 public LispMapRecord readFrom(ByteBuf byteBuf) throws LispParseError {
Jian Li47671902016-08-11 01:18:18 +0900229
230 // Record TTL -> 32 bits
231 int recordTtl = byteBuf.readInt();
232
233 // Locator count -> 8 bits
234 int locatorCount = byteBuf.readUnsignedShort();
235
236 // EID mask length -> 8 bits
237 byte maskLength = (byte) byteBuf.readUnsignedByte();
238
239 // TODO: need to de-serialize LispMapReplyAction
240
241 byte actionWithFlag = byteBuf.readByte();
242
243 // authoritative flag -> 1 bit
244 boolean authoritative = ByteOperator.getBit(actionWithFlag, AUTHORITATIVE_INDEX);
245
246 // let's skip the reserved field
247 byteBuf.skipBytes(RESERVED_SKIP_LENGTH);
248
249 // Map version number -> 12 bits, we treat Rsvd field is all zero
250 short mapVersionNumber = (short) byteBuf.readUnsignedShort();
251
252 // TODO: need to de-serialize EID AFI address
253
254 List<LispLocatorRecord> locators = Lists.newArrayList();
255 for (int i = 0; i < locatorCount; i++) {
256 locators.add(new DefaultLispLocatorRecord.LocatorRecordReader().readFrom(byteBuf));
257 }
258
259 return new DefaultMapRecordBuilder()
260 .withRecordTtl(recordTtl)
261 .withLocatorCount(locatorCount)
262 .withMaskLength(maskLength)
263 .withAuthoritative(authoritative)
264 .withMapVersionNumber(mapVersionNumber)
265 .withLocators(locators)
266 .build();
Jian Li26069e22016-08-10 22:00:52 +0900267 }
268 }
Jian Li10a09062016-07-26 23:58:50 +0900269}