blob: 860da6271dbcbf9e7c43a082204f19d6d860bbf6 [file] [log] [blame]
Jian Li672ebda2017-02-06 20:21:04 +09001/*
2 * Copyright 2017-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;
22import org.onosproject.lisp.msg.exceptions.LispReaderException;
23import org.onosproject.lisp.msg.exceptions.LispWriterException;
24import org.onosproject.lisp.msg.types.LispAfiAddress;
25import org.onosproject.lisp.msg.types.LispAfiAddress.AfiAddressWriter;
26
27import static com.google.common.base.MoreObjects.toStringHelper;
28
29/**
30 * A default implementation class of LISP generic locator interface.
31 */
32public class DefaultLispGenericLocator implements LispGenericLocator {
33
Jian Li3282a342017-05-23 14:30:15 +090034 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;
Jian Li672ebda2017-02-06 20:21:04 +090042
43 private static final int LOCAL_LOCATOR_SHIFT_BIT = 2;
44 private static final int PROBED_SHIFT_BIT = 1;
45
46 private static final int ENABLE_BIT = 1;
47 private static final int DISABLE_BIT = 0;
48
49 private static final int SKIP_UNUSED_FLAG_LENGTH = 1;
50 private static final int LOCAL_LOCATOR_INDEX = 2;
51 private static final int RLOC_PROBED_INDEX = 1;
52 private static final int ROUTED_INDEX = 0;
53
54 /**
55 * A private constructor that protects object instantiation from external.
56 *
57 * @param priority uni-cast priority
58 * @param weight uni-cast weight
59 * @param multicastPriority multi-cast priority
60 * @param multicastWeight multi-cast weight
61 * @param localLocator local locator flag
62 * @param rlocProbed RLOC probed flag
63 * @param routed routed flag
64 * @param locatorAfi locator AFI
65 */
Jian Li3282a342017-05-23 14:30:15 +090066 DefaultLispGenericLocator(byte priority, byte weight, byte multicastPriority,
67 byte multicastWeight, boolean localLocator,
68 boolean rlocProbed, boolean routed,
69 LispAfiAddress locatorAfi) {
Jian Li672ebda2017-02-06 20:21:04 +090070 this.priority = priority;
71 this.weight = weight;
72 this.multicastPriority = multicastPriority;
73 this.multicastWeight = multicastWeight;
74 this.localLocator = localLocator;
75 this.rlocProbed = rlocProbed;
76 this.routed = routed;
77 this.locatorAfi = locatorAfi;
78 }
79
80 @Override
81 public byte getPriority() {
82 return priority;
83 }
84
85 @Override
86 public byte getWeight() {
87 return weight;
88 }
89
90 @Override
91 public byte getMulticastPriority() {
92 return multicastPriority;
93 }
94
95 @Override
96 public byte getMulticastWeight() {
97 return multicastWeight;
98 }
99
100 @Override
101 public boolean isLocalLocator() {
102 return localLocator;
103 }
104
105 @Override
106 public boolean isRlocProbed() {
107 return rlocProbed;
108 }
109
110 @Override
111 public boolean isRouted() {
112 return routed;
113 }
114
115 @Override
116 public LispAfiAddress getLocatorAfi() {
117 return locatorAfi;
118 }
119
120 @Override
121 public void writeTo(ByteBuf byteBuf) throws LispWriterException {
122 }
123
124 @Override
125 public String toString() {
126 return toStringHelper(this)
127 .add("priority", priority)
128 .add("weight", weight)
129 .add("multi-cast priority", multicastPriority)
130 .add("multi-cast weight", multicastWeight)
131 .add("local locator", localLocator)
132 .add("RLOC probed", rlocProbed)
133 .add("routed", routed)
134 .add("locator AFI", locatorAfi).toString();
135 }
136
137 @Override
138 public boolean equals(Object o) {
139 if (this == o) {
140 return true;
141 }
142 if (o == null || getClass() != o.getClass()) {
143 return false;
144 }
145 DefaultLispGenericLocator that = (DefaultLispGenericLocator) o;
146 return Objects.equal(priority, that.priority) &&
147 Objects.equal(weight, that.weight) &&
148 Objects.equal(multicastPriority, that.multicastPriority) &&
149 Objects.equal(multicastWeight, that.multicastWeight) &&
150 Objects.equal(localLocator, that.localLocator) &&
151 Objects.equal(rlocProbed, that.rlocProbed) &&
152 Objects.equal(routed, that.routed) &&
153 Objects.equal(locatorAfi, that.locatorAfi);
154 }
155
156 @Override
157 public int hashCode() {
158 return Objects.hashCode(priority, weight, multicastPriority,
159 multicastWeight, localLocator, rlocProbed, routed, locatorAfi);
160 }
161
162 public abstract static class AbstractGenericLocatorBuilder<T>
163 implements GenericLocatorBuilder<T> {
Jian Li3282a342017-05-23 14:30:15 +0900164 byte priority;
165 byte weight;
166 byte multicastPriority;
167 byte multicastWeight;
168 boolean localLocator;
169 boolean rlocProbed;
170 boolean routed;
171 LispAfiAddress locatorAfi;
Jian Li672ebda2017-02-06 20:21:04 +0900172
173 @Override
174 public T withPriority(byte priority) {
175 this.priority = priority;
176 return (T) this;
177 }
178
179 @Override
180 public T withWeight(byte weight) {
181 this.weight = weight;
182 return (T) this;
183 }
184
185 @Override
186 public T withMulticastPriority(byte priority) {
187 this.multicastPriority = priority;
188 return (T) this;
189 }
190
191 @Override
192 public T withMulticastWeight(byte weight) {
193 this.multicastWeight = weight;
194 return (T) this;
195 }
196
197 @Override
198 public T withLocalLocator(boolean localLocator) {
199 this.localLocator = localLocator;
200 return (T) this;
201 }
202
203 @Override
204 public T withRlocProbed(boolean rlocProbed) {
205 this.rlocProbed = rlocProbed;
206 return (T) this;
207 }
208
209 @Override
210 public T withRouted(boolean routed) {
211 this.routed = routed;
212 return (T) this;
213 }
214
215 @Override
216 public T withLocatorAfi(LispAfiAddress locatorAfi) {
217 this.locatorAfi = locatorAfi;
218 return (T) this;
219 }
220 }
221
222 /**
223 * Deserializes LispGenericLocator message portion.
224 *
225 * @param byteBuf byte buffer
226 * @return LispGenericLocator
227 * @throws LispParseError LISP message parse error
228 * @throws LispReaderException LISP message reader exception
229 */
230 public static LispGenericLocator deserialize(ByteBuf byteBuf)
231 throws LispParseError,
232 LispReaderException {
233 // priority -> 8 bits
234 byte priority = (byte) byteBuf.readUnsignedByte();
235
236 // weight -> 8 bits
237 byte weight = (byte) byteBuf.readUnsignedByte();
238
239 // multi-cast priority -> 8 bits
240 byte multicastPriority = (byte) byteBuf.readUnsignedByte();
241
242 // multi-cast weight -> 8 bits
243 byte multicastWeight = (byte) byteBuf.readUnsignedByte();
244
245 // let's skip unused flags
246 byteBuf.skipBytes(SKIP_UNUSED_FLAG_LENGTH);
247
248 byte flags = byteBuf.readByte();
249
250 // local locator flag -> 1 bit
251 boolean localLocator = ByteOperator.getBit(flags, LOCAL_LOCATOR_INDEX);
252
253 // rloc probe flag -> 1 bit
254 boolean rlocProbed = ByteOperator.getBit(flags, RLOC_PROBED_INDEX);
255
256 // routed flag -> 1 bit
257 boolean routed = ByteOperator.getBit(flags, ROUTED_INDEX);
258
259 LispAfiAddress address = new LispAfiAddress.AfiAddressReader().readFrom(byteBuf);
260
261 return new DefaultLispGenericLocator(priority, weight, multicastPriority,
262 multicastWeight, localLocator, rlocProbed, routed, address);
263 }
264
265 /**
266 * Serializes LispGenericLocator message portion.
267 *
268 * @param byteBuf byte buffer
269 * @param genericLocator generic locator
270 * @throws LispWriterException LISP message writer exception
271 */
272 public static void serialize(ByteBuf byteBuf, LispGenericLocator genericLocator)
273 throws LispWriterException {
274 // priority
275 byteBuf.writeByte(genericLocator.getPriority());
276
277 // weight
278 byteBuf.writeByte(genericLocator.getWeight());
279
280 // multicast priority
281 byteBuf.writeByte(genericLocator.getMulticastPriority());
282
283 // multicast weight
284 byteBuf.writeByte(genericLocator.getMulticastWeight());
285
286 // unused flags
287 byteBuf.writeByte((short) 0);
288
289 // localLocator flag
290 short localLocator = DISABLE_BIT;
291 if (genericLocator.isLocalLocator()) {
292 localLocator = (byte) (ENABLE_BIT << LOCAL_LOCATOR_SHIFT_BIT);
293 }
294
295 // rlocProbed flag
296 short probed = DISABLE_BIT;
297 if (genericLocator.isRlocProbed()) {
298 probed = (byte) (ENABLE_BIT << PROBED_SHIFT_BIT);
299 }
300
301 // routed flag
302 short routed = DISABLE_BIT;
303 if (genericLocator.isRouted()) {
304 routed = (byte) ENABLE_BIT;
305 }
306
307 byteBuf.writeByte((byte) (localLocator + probed + routed));
308
309 // EID prefix AFI with EID prefix
310 AfiAddressWriter afiAddressWriter = new AfiAddressWriter();
311 afiAddressWriter.writeTo(byteBuf, genericLocator.getLocatorAfi());
312 }
313}