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