blob: 48f7d4749904c0777fd7b5ad573a38743d0ec467 [file] [log] [blame]
Jian Li99f83ef2016-11-03 19:14:25 +01001/*
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.types;
17
18import io.netty.buffer.ByteBuf;
19import org.onlab.util.ByteOperator;
20import org.onosproject.lisp.msg.exceptions.LispParseError;
21import org.onosproject.lisp.msg.exceptions.LispReaderException;
22import org.onosproject.lisp.msg.exceptions.LispWriterException;
23import org.onosproject.lisp.msg.types.LispAfiAddress.AfiAddressReader;
Jian Li5e505c62016-12-05 02:44:24 +090024import org.onosproject.lisp.msg.types.LispAfiAddress.AfiAddressWriter;
Jian Li99f83ef2016-11-03 19:14:25 +010025
26import java.util.Objects;
27
28import static com.google.common.base.MoreObjects.toStringHelper;
29
30/**
31 * Traffic Engineering record class.
32 */
33public class LispTeRecord {
34
35 private final boolean lookup;
36 private final boolean rlocProbe;
37 private final boolean strict;
38 private final LispAfiAddress rtrRlocAddress;
39
40 /**
41 * Initializes TE record.
42 *
43 * @param lookup lookup bit
44 * @param rlocProbe rloc probe bit
45 * @param strict strict bit
46 * @param rtrAddress RTR address
47 */
Jian Li89c9ca92016-11-11 04:09:02 +090048 public LispTeRecord(boolean lookup, boolean rlocProbe,
49 boolean strict, LispAfiAddress rtrAddress) {
Jian Li99f83ef2016-11-03 19:14:25 +010050 this.lookup = lookup;
51 this.rlocProbe = rlocProbe;
52 this.strict = strict;
53 this.rtrRlocAddress = rtrAddress;
54 }
55
56 /**
57 * Obtains lookup bit flag.
58 *
59 * @return lookup bit flag
60 */
61 public boolean isLookup() {
62 return lookup;
63 }
64
65 /**
66 * Obtains RLOC probe bit flag.
67 *
68 * @return RLOC probe bit flag
69 */
70 public boolean isRlocProbe() {
71 return rlocProbe;
72 }
73
74 /**
75 * Obtains strict bit flag.
76 *
77 * @return strict bit flag
78 */
79 public boolean isStrict() {
80 return strict;
81 }
82
83 /**
84 * Obtains Re-encapsulated RLOC address.
85 *
86 * @return Re-encapsulated RLOC address
87 */
88 public LispAfiAddress getRtrRlocAddress() {
89 return rtrRlocAddress;
90 }
91
92 @Override
93 public int hashCode() {
94 return Objects.hash(lookup, rlocProbe, strict, rtrRlocAddress);
95 }
96
97 @Override
98 public boolean equals(Object obj) {
99 if (this == obj) {
100 return true;
101 }
102
103 if (obj instanceof LispTeRecord) {
104 final LispTeRecord other = (LispTeRecord) obj;
105 return Objects.equals(this.lookup, other.lookup) &&
106 Objects.equals(this.rlocProbe, other.rlocProbe) &&
107 Objects.equals(this.strict, other.strict) &&
108 Objects.equals(this.rtrRlocAddress, other.rtrRlocAddress);
109 }
110 return false;
111 }
112
113 @Override
114 public String toString() {
115 return toStringHelper(this)
116 .add("Lookup bit", lookup)
117 .add("RLOC probe bit", rlocProbe)
118 .add("strict bit", strict)
119 .add("RTR address", rtrRlocAddress)
120 .toString();
121 }
122
123 public static final class TeRecordBuilder {
124 private boolean lookup;
125 private boolean rlocProbe;
126 private boolean strict;
127 private LispAfiAddress rtrRlocAddress;
128
129 /**
130 * Sets lookup flag.
131 *
132 * @param lookup lookup flag
133 * @return TeRecordBuilder object
134 */
135 public TeRecordBuilder withIsLookup(boolean lookup) {
136 this.lookup = lookup;
137 return this;
138 }
139
140 /**
141 * Sets RLOC probe flag.
142 *
143 * @param rlocProbe RLOC probe flag
144 * @return TeRecordBuilder object
145 */
146 public TeRecordBuilder withIsRlocProbe(boolean rlocProbe) {
147 this.rlocProbe = rlocProbe;
148 return this;
149 }
150
151 /**
152 * Sets strict flag.
153 *
154 * @param strict strict flag
155 * @return TeRecordBuilder object
156 */
157 public TeRecordBuilder withIsStrict(boolean strict) {
158 this.strict = strict;
159 return this;
160 }
161
162 /**
163 * Sets RTR RLOC address.
164 *
165 * @param rtrRlocAddress RTR RLOC address
166 * @return TeRecordBuilder object
167 */
168 public TeRecordBuilder withRtrRlocAddress(LispAfiAddress rtrRlocAddress) {
169 this.rtrRlocAddress = rtrRlocAddress;
170 return this;
171 }
172
173 /**
174 * Builds TeRecord instance.
175 *
176 * @return TeRcord instance
177 */
178 public LispTeRecord build() {
179
180 return new LispTeRecord(lookup, rlocProbe, strict, rtrRlocAddress);
181 }
182 }
183
184 /**
185 * Traffic Engineering record reader class.
186 */
187 public static class TeRecordReader implements LispAddressReader<LispTeRecord> {
188
189 private static final int RESERVED_SKIP_LENGTH = 1;
190
191 private static final int STRICT_INDEX = 1;
192 private static final int RLOC_PROBE_INDEX = 2;
193 private static final int LOOKUP_INDEX = 3;
194
195 @Override
Jian Li3a99e712016-12-16 21:23:16 +0900196 public LispTeRecord readFrom(ByteBuf byteBuf)
197 throws LispParseError, LispReaderException {
Jian Li99f83ef2016-11-03 19:14:25 +0100198
199 // let's skip reserved 3
200 byteBuf.skipBytes(RESERVED_SKIP_LENGTH);
201
202 byte flags = byteBuf.readByte();
203
204 // lookup -> 1 bit
205 boolean lookup = ByteOperator.getBit(flags, LOOKUP_INDEX);
206
207 // rlocProbe -> 1 bit
208 boolean rlocProbe = ByteOperator.getBit(flags, RLOC_PROBE_INDEX);
209
210 // strict -> 1 bit
211 boolean strict = ByteOperator.getBit(flags, STRICT_INDEX);
212
213 AfiAddressReader reader = new AfiAddressReader();
214
215 LispAfiAddress rtrAddress = reader.readFrom(byteBuf);
216
217 return new LispTeRecord(lookup, rlocProbe, strict, rtrAddress);
218 }
219 }
220
221 /**
222 * Traffic Engineering record writer class.
223 */
224 public static class TeRecordWriter implements LispAddressWriter<LispTeRecord> {
225
226 private static final int LOOKUP_FLAG_SHIFT_BIT = 3;
227 private static final int RLOC_PROBE_FLAG_SHIFT_BIT = 2;
228 private static final int STRICT_FLAG_SHIFT_BIT = 1;
229
230 private static final int ENABLE_BIT = 1;
231 private static final int DISABLE_BIT = 0;
232
233 private static final int UNUSED_ZERO = 0;
234
235 @Override
Jian Li3a99e712016-12-16 21:23:16 +0900236 public void writeTo(ByteBuf byteBuf, LispTeRecord record)
237 throws LispWriterException {
Jian Li99f83ef2016-11-03 19:14:25 +0100238
239 byteBuf.writeByte(UNUSED_ZERO);
240
241 // lookup flag
242 byte lookup = DISABLE_BIT;
243 if (record.isLookup()) {
244 lookup = (byte) (ENABLE_BIT << LOOKUP_FLAG_SHIFT_BIT);
245 }
246
247 // RLOC probe flag
248 byte rlocProbe = DISABLE_BIT;
249 if (record.isRlocProbe()) {
250 rlocProbe = (byte) (ENABLE_BIT << RLOC_PROBE_FLAG_SHIFT_BIT);
251 }
252
253 // strict flag
254 byte strict = DISABLE_BIT;
255 if (record.isStrict()) {
256 strict = (byte) (ENABLE_BIT << STRICT_FLAG_SHIFT_BIT);
257 }
258
259 byteBuf.writeByte((byte) (lookup + rlocProbe + strict));
260
261 // RTR RLOC address
Jian Li5e505c62016-12-05 02:44:24 +0900262 AfiAddressWriter writer = new AfiAddressWriter();
Jian Li99f83ef2016-11-03 19:14:25 +0100263 writer.writeTo(byteBuf, record.rtrRlocAddress);
264 }
265 }
266}