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