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