blob: e242a5d4f8045cae9d454e74913e8271b4fbb1fb [file] [log] [blame]
Jian Li47671902016-08-11 01:18:18 +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
18import com.google.common.base.Objects;
19import io.netty.buffer.ByteBuf;
20import org.onlab.util.ByteOperator;
21import org.onosproject.lisp.msg.exceptions.LispParseError;
Jian Lia7b394d2016-08-21 23:11:46 +090022import org.onosproject.lisp.msg.exceptions.LispReaderException;
Jian Liedc5db12016-08-23 17:30:19 +090023import org.onosproject.lisp.msg.exceptions.LispWriterException;
Jian Li47671902016-08-11 01:18:18 +090024import org.onosproject.lisp.msg.types.LispAfiAddress;
25
26import static com.google.common.base.MoreObjects.toStringHelper;
Jian Lid4e63702016-08-30 18:29:20 +090027import static com.google.common.base.Preconditions.checkNotNull;
Jian Liedc5db12016-08-23 17:30:19 +090028import static org.onosproject.lisp.msg.types.LispAfiAddress.AfiAddressWriter;
Jian Li47671902016-08-11 01:18:18 +090029
30/**
31 * Default implementation of LispLocatorRecord.
32 */
33public final class DefaultLispLocatorRecord implements LispLocatorRecord {
34
35 private final byte priority;
36 private final byte weight;
37 private final byte multicastPriority;
38 private final byte multicastWeight;
39 private final boolean localLocator;
40 private final boolean rlocProbed;
41 private final boolean routed;
42 private final LispAfiAddress locatorAfi;
43
Yoonseon Hanca814bf2016-09-12 11:37:48 -070044 static final LocatorRecordWriter WRITER;
45 static {
46 WRITER = new LocatorRecordWriter();
47 }
48
Jian Li47671902016-08-11 01:18:18 +090049 /**
50 * A private constructor that protects object instantiation from external.
51 *
52 * @param priority uni-cast priority
53 * @param weight uni-cast weight
54 * @param multicastPriority multi-cast priority
55 * @param multicastWeight multi-cast weight
56 * @param localLocator local locator flag
57 * @param rlocProbed RLOC probed flag
58 * @param routed routed flag
59 * @param locatorAfi locator AFI
60 */
61 private DefaultLispLocatorRecord(byte priority, byte weight, byte multicastPriority,
62 byte multicastWeight, boolean localLocator, boolean rlocProbed,
63 boolean routed, LispAfiAddress locatorAfi) {
64 this.priority = priority;
65 this.weight = weight;
66 this.multicastPriority = multicastPriority;
67 this.multicastWeight = multicastWeight;
68 this.localLocator = localLocator;
69 this.rlocProbed = rlocProbed;
70 this.routed = routed;
71 this.locatorAfi = locatorAfi;
72 }
73
74 @Override
75 public byte getPriority() {
76 return priority;
77 }
78
79 @Override
80 public byte getWeight() {
81 return weight;
82 }
83
84 @Override
85 public byte getMulticastPriority() {
86 return multicastPriority;
87 }
88
89 @Override
90 public byte getMulticastWeight() {
91 return multicastWeight;
92 }
93
94 @Override
95 public boolean isLocalLocator() {
96 return localLocator;
97 }
98
99 @Override
100 public boolean isRlocProbed() {
101 return rlocProbed;
102 }
103
104 @Override
105 public boolean isRouted() {
106 return routed;
107 }
108
109 @Override
110 public LispAfiAddress getLocatorAfi() {
111 return locatorAfi;
112 }
113
114 @Override
Yoonseon Hanca814bf2016-09-12 11:37:48 -0700115 public void writeTo(ByteBuf byteBuf) throws LispWriterException {
116 WRITER.writeTo(byteBuf, this);
Jian Li47671902016-08-11 01:18:18 +0900117 }
118
119 @Override
120 public String toString() {
121 return toStringHelper(this)
122 .add("priority", priority)
123 .add("weight", weight)
124 .add("multi-cast priority", multicastPriority)
125 .add("multi-cast weight", multicastWeight)
126 .add("local locator", localLocator)
127 .add("RLOC probed", rlocProbed)
128 .add("routed", routed)
129 .add("locator AFI", locatorAfi).toString();
130 }
131
132 @Override
133 public boolean equals(Object o) {
134 if (this == o) {
135 return true;
136 }
137 if (o == null || getClass() != o.getClass()) {
138 return false;
139 }
140 DefaultLispLocatorRecord that = (DefaultLispLocatorRecord) o;
141 return Objects.equal(priority, that.priority) &&
142 Objects.equal(weight, that.weight) &&
143 Objects.equal(multicastPriority, that.multicastPriority) &&
144 Objects.equal(multicastWeight, that.multicastWeight) &&
145 Objects.equal(localLocator, that.localLocator) &&
146 Objects.equal(rlocProbed, that.rlocProbed) &&
147 Objects.equal(routed, that.routed) &&
148 Objects.equal(locatorAfi, that.locatorAfi);
149 }
150
151 @Override
152 public int hashCode() {
153 return Objects.hashCode(priority, weight, multicastPriority,
154 multicastWeight, localLocator, rlocProbed, routed, locatorAfi);
155 }
156
157 public static final class DefaultLocatorRecordBuilder implements LocatorRecordBuilder {
158
159 private byte priority;
160 private byte weight;
161 private byte multicastPriority;
162 private byte multicastWeight;
163 private boolean localLocator;
164 private boolean rlocProbed;
165 private boolean routed;
166 private LispAfiAddress locatorAfi;
167
168 @Override
169 public LocatorRecordBuilder withPriority(byte priority) {
170 this.priority = priority;
171 return this;
172 }
173
174 @Override
175 public LocatorRecordBuilder withWeight(byte weight) {
176 this.weight = weight;
177 return this;
178 }
179
180 @Override
181 public LocatorRecordBuilder withMulticastPriority(byte priority) {
182 this.multicastPriority = priority;
183 return this;
184 }
185
186 @Override
187 public LocatorRecordBuilder withMulticastWeight(byte weight) {
188 this.multicastWeight = weight;
189 return this;
190 }
191
192 @Override
193 public LocatorRecordBuilder withLocalLocator(boolean localLocator) {
194 this.localLocator = localLocator;
195 return this;
196 }
197
198 @Override
199 public LocatorRecordBuilder withRlocProbed(boolean rlocProbed) {
200 this.rlocProbed = rlocProbed;
201 return this;
202 }
203
204 @Override
205 public LocatorRecordBuilder withRouted(boolean routed) {
206 this.routed = routed;
207 return this;
208 }
209
210 @Override
211 public LocatorRecordBuilder withLocatorAfi(LispAfiAddress locatorAfi) {
212 this.locatorAfi = locatorAfi;
213 return this;
214 }
215
216 @Override
217 public LispLocatorRecord build() {
Jian Lid4e63702016-08-30 18:29:20 +0900218
219 checkNotNull(locatorAfi, "Must specify a locator address");
220
Jian Li47671902016-08-11 01:18:18 +0900221 return new DefaultLispLocatorRecord(priority, weight, multicastPriority,
222 multicastWeight, localLocator, rlocProbed, routed, locatorAfi);
223 }
224 }
225
226 /**
227 * A LISP message reader for LocatorRecord portion.
228 */
229 public static final class LocatorRecordReader implements LispMessageReader<LispLocatorRecord> {
230
231 private static final int SKIP_UNUSED_FLAG_LENGTH = 1;
232 private static final int LOCAL_LOCATOR_INDEX = 2;
233 private static final int RLOC_PROBED_INDEX = 1;
234 private static final int ROUTED_INDEX = 0;
235
236 @Override
Jian Lia7b394d2016-08-21 23:11:46 +0900237 public LispLocatorRecord readFrom(ByteBuf byteBuf) throws LispParseError, LispReaderException {
Jian Li47671902016-08-11 01:18:18 +0900238
239 // priority -> 8 bits
240 byte priority = (byte) byteBuf.readUnsignedByte();
241
242 // weight -> 8 bits
243 byte weight = (byte) byteBuf.readUnsignedByte();
244
245 // multi-cast priority -> 8 bits
246 byte multicastPriority = (byte) byteBuf.readUnsignedByte();
247
248 // multi-cast weight -> 8 bits
249 byte multicastWeight = (byte) byteBuf.readUnsignedByte();
250
251 // let's skip unused flags
252 byteBuf.skipBytes(SKIP_UNUSED_FLAG_LENGTH);
253
254 byte flags = byteBuf.readByte();
255
256 // local locator flag -> 1 bit
257 boolean localLocator = ByteOperator.getBit(flags, LOCAL_LOCATOR_INDEX);
258
259 // rloc probe flag -> 1 bit
260 boolean rlocProbed = ByteOperator.getBit(flags, RLOC_PROBED_INDEX);
261
262 // routed flag -> 1 bit
263 boolean routed = ByteOperator.getBit(flags, ROUTED_INDEX);
264
Jian Lia7b394d2016-08-21 23:11:46 +0900265 LispAfiAddress address = new LispAfiAddress.AfiAddressReader().readFrom(byteBuf);
Jian Li47671902016-08-11 01:18:18 +0900266
267 return new DefaultLocatorRecordBuilder()
268 .withPriority(priority)
269 .withWeight(weight)
270 .withMulticastPriority(multicastPriority)
271 .withMulticastWeight(multicastWeight)
272 .withLocalLocator(localLocator)
273 .withRlocProbed(rlocProbed)
274 .withRouted(routed)
Jian Lia7b394d2016-08-21 23:11:46 +0900275 .withLocatorAfi(address)
Jian Li47671902016-08-11 01:18:18 +0900276 .build();
277 }
278 }
Jian Liedc5db12016-08-23 17:30:19 +0900279
280 /**
281 * A LISP message writer for LocatorRecord portion.
282 */
283 public static final class LocatorRecordWriter implements LispMessageWriter<LispLocatorRecord> {
284
285 private static final int LOCAL_LOCATOR_SHIFT_BIT = 2;
286 private static final int PROBED_SHIFT_BIT = 1;
287
288 private static final int ENABLE_BIT = 1;
289 private static final int DISABLE_BIT = 0;
290
291 @Override
292 public void writeTo(ByteBuf byteBuf, LispLocatorRecord message) throws LispWriterException {
293
294 // priority
295 byteBuf.writeByte(message.getPriority());
296
297 // weight
298 byteBuf.writeByte(message.getWeight());
299
300 // multicast priority
301 byteBuf.writeByte(message.getMulticastPriority());
302
303 // multicast weight
304 byteBuf.writeByte(message.getMulticastWeight());
305
306 // unused flags
307 byteBuf.writeByte((short) 0);
308
309 // localLocator flag
310 short localLocator = DISABLE_BIT;
311 if (message.isLocalLocator()) {
312 localLocator = (byte) (ENABLE_BIT << LOCAL_LOCATOR_SHIFT_BIT);
313 }
314
315 // rlocProbed flag
316 short probed = DISABLE_BIT;
317 if (message.isRlocProbed()) {
318 probed = (byte) (ENABLE_BIT << PROBED_SHIFT_BIT);
319 }
320
321 // routed flag
322 short routed = DISABLE_BIT;
323 if (message.isRouted()) {
324 routed = (byte) ENABLE_BIT;
325 }
326
327 byteBuf.writeByte((byte) (localLocator + probed + routed));
328
329 // EID prefix AFI with EID prefix
330 AfiAddressWriter afiAddressWriter = new AfiAddressWriter();
331 afiAddressWriter.writeTo(byteBuf, message.getLocatorAfi());
332 }
333 }
Jian Li47671902016-08-11 01:18:18 +0900334}