blob: 2936b4b9c471430cf3e7c4cab58dd1725c71ecad [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
34 protected final byte priority;
35 protected final byte weight;
36 protected final byte multicastPriority;
37 protected final byte multicastWeight;
38 protected final boolean localLocator;
39 protected final boolean rlocProbed;
40 protected final boolean routed;
41 protected final LispAfiAddress locatorAfi;
42
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 */
66 protected DefaultLispGenericLocator(byte priority, byte weight,
67 byte multicastPriority,
68 byte multicastWeight,
69 boolean localLocator, boolean rlocProbed,
70 boolean routed, LispAfiAddress locatorAfi) {
71 this.priority = priority;
72 this.weight = weight;
73 this.multicastPriority = multicastPriority;
74 this.multicastWeight = multicastWeight;
75 this.localLocator = localLocator;
76 this.rlocProbed = rlocProbed;
77 this.routed = routed;
78 this.locatorAfi = locatorAfi;
79 }
80
81 @Override
82 public byte getPriority() {
83 return priority;
84 }
85
86 @Override
87 public byte getWeight() {
88 return weight;
89 }
90
91 @Override
92 public byte getMulticastPriority() {
93 return multicastPriority;
94 }
95
96 @Override
97 public byte getMulticastWeight() {
98 return multicastWeight;
99 }
100
101 @Override
102 public boolean isLocalLocator() {
103 return localLocator;
104 }
105
106 @Override
107 public boolean isRlocProbed() {
108 return rlocProbed;
109 }
110
111 @Override
112 public boolean isRouted() {
113 return routed;
114 }
115
116 @Override
117 public LispAfiAddress getLocatorAfi() {
118 return locatorAfi;
119 }
120
121 @Override
122 public void writeTo(ByteBuf byteBuf) throws LispWriterException {
123 }
124
125 @Override
126 public String toString() {
127 return toStringHelper(this)
128 .add("priority", priority)
129 .add("weight", weight)
130 .add("multi-cast priority", multicastPriority)
131 .add("multi-cast weight", multicastWeight)
132 .add("local locator", localLocator)
133 .add("RLOC probed", rlocProbed)
134 .add("routed", routed)
135 .add("locator AFI", locatorAfi).toString();
136 }
137
138 @Override
139 public boolean equals(Object o) {
140 if (this == o) {
141 return true;
142 }
143 if (o == null || getClass() != o.getClass()) {
144 return false;
145 }
146 DefaultLispGenericLocator that = (DefaultLispGenericLocator) o;
147 return Objects.equal(priority, that.priority) &&
148 Objects.equal(weight, that.weight) &&
149 Objects.equal(multicastPriority, that.multicastPriority) &&
150 Objects.equal(multicastWeight, that.multicastWeight) &&
151 Objects.equal(localLocator, that.localLocator) &&
152 Objects.equal(rlocProbed, that.rlocProbed) &&
153 Objects.equal(routed, that.routed) &&
154 Objects.equal(locatorAfi, that.locatorAfi);
155 }
156
157 @Override
158 public int hashCode() {
159 return Objects.hashCode(priority, weight, multicastPriority,
160 multicastWeight, localLocator, rlocProbed, routed, locatorAfi);
161 }
162
163 public abstract static class AbstractGenericLocatorBuilder<T>
164 implements GenericLocatorBuilder<T> {
165 protected byte priority;
166 protected byte weight;
167 protected byte multicastPriority;
168 protected byte multicastWeight;
169 protected boolean localLocator;
170 protected boolean rlocProbed;
171 protected boolean routed;
172 protected LispAfiAddress locatorAfi;
173
174 @Override
175 public T withPriority(byte priority) {
176 this.priority = priority;
177 return (T) this;
178 }
179
180 @Override
181 public T withWeight(byte weight) {
182 this.weight = weight;
183 return (T) this;
184 }
185
186 @Override
187 public T withMulticastPriority(byte priority) {
188 this.multicastPriority = priority;
189 return (T) this;
190 }
191
192 @Override
193 public T withMulticastWeight(byte weight) {
194 this.multicastWeight = weight;
195 return (T) this;
196 }
197
198 @Override
199 public T withLocalLocator(boolean localLocator) {
200 this.localLocator = localLocator;
201 return (T) this;
202 }
203
204 @Override
205 public T withRlocProbed(boolean rlocProbed) {
206 this.rlocProbed = rlocProbed;
207 return (T) this;
208 }
209
210 @Override
211 public T withRouted(boolean routed) {
212 this.routed = routed;
213 return (T) this;
214 }
215
216 @Override
217 public T withLocatorAfi(LispAfiAddress locatorAfi) {
218 this.locatorAfi = locatorAfi;
219 return (T) this;
220 }
221 }
222
223 /**
224 * Deserializes LispGenericLocator message portion.
225 *
226 * @param byteBuf byte buffer
227 * @return LispGenericLocator
228 * @throws LispParseError LISP message parse error
229 * @throws LispReaderException LISP message reader exception
230 */
231 public static LispGenericLocator deserialize(ByteBuf byteBuf)
232 throws LispParseError,
233 LispReaderException {
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
260 LispAfiAddress address = new LispAfiAddress.AfiAddressReader().readFrom(byteBuf);
261
262 return new DefaultLispGenericLocator(priority, weight, multicastPriority,
263 multicastWeight, localLocator, rlocProbed, routed, address);
264 }
265
266 /**
267 * Serializes LispGenericLocator message portion.
268 *
269 * @param byteBuf byte buffer
270 * @param genericLocator generic locator
271 * @throws LispWriterException LISP message writer exception
272 */
273 public static void serialize(ByteBuf byteBuf, LispGenericLocator genericLocator)
274 throws LispWriterException {
275 // priority
276 byteBuf.writeByte(genericLocator.getPriority());
277
278 // weight
279 byteBuf.writeByte(genericLocator.getWeight());
280
281 // multicast priority
282 byteBuf.writeByte(genericLocator.getMulticastPriority());
283
284 // multicast weight
285 byteBuf.writeByte(genericLocator.getMulticastWeight());
286
287 // unused flags
288 byteBuf.writeByte((short) 0);
289
290 // localLocator flag
291 short localLocator = DISABLE_BIT;
292 if (genericLocator.isLocalLocator()) {
293 localLocator = (byte) (ENABLE_BIT << LOCAL_LOCATOR_SHIFT_BIT);
294 }
295
296 // rlocProbed flag
297 short probed = DISABLE_BIT;
298 if (genericLocator.isRlocProbed()) {
299 probed = (byte) (ENABLE_BIT << PROBED_SHIFT_BIT);
300 }
301
302 // routed flag
303 short routed = DISABLE_BIT;
304 if (genericLocator.isRouted()) {
305 routed = (byte) ENABLE_BIT;
306 }
307
308 byteBuf.writeByte((byte) (localLocator + probed + routed));
309
310 // EID prefix AFI with EID prefix
311 AfiAddressWriter afiAddressWriter = new AfiAddressWriter();
312 afiAddressWriter.writeTo(byteBuf, genericLocator.getLocatorAfi());
313 }
314}