blob: 3a496d6d895683985c29dfcd42c47ae4375cf6f5 [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
196 public LispTeRecord readFrom(ByteBuf byteBuf) throws LispParseError, LispReaderException {
197
198 // let's skip reserved 3
199 byteBuf.skipBytes(RESERVED_SKIP_LENGTH);
200
201 byte flags = byteBuf.readByte();
202
203 // lookup -> 1 bit
204 boolean lookup = ByteOperator.getBit(flags, LOOKUP_INDEX);
205
206 // rlocProbe -> 1 bit
207 boolean rlocProbe = ByteOperator.getBit(flags, RLOC_PROBE_INDEX);
208
209 // strict -> 1 bit
210 boolean strict = ByteOperator.getBit(flags, STRICT_INDEX);
211
212 AfiAddressReader reader = new AfiAddressReader();
213
214 LispAfiAddress rtrAddress = reader.readFrom(byteBuf);
215
216 return new LispTeRecord(lookup, rlocProbe, strict, rtrAddress);
217 }
218 }
219
220 /**
221 * Traffic Engineering record writer class.
222 */
223 public static class TeRecordWriter implements LispAddressWriter<LispTeRecord> {
224
225 private static final int LOOKUP_FLAG_SHIFT_BIT = 3;
226 private static final int RLOC_PROBE_FLAG_SHIFT_BIT = 2;
227 private static final int STRICT_FLAG_SHIFT_BIT = 1;
228
229 private static final int ENABLE_BIT = 1;
230 private static final int DISABLE_BIT = 0;
231
232 private static final int UNUSED_ZERO = 0;
233
234 @Override
235 public void writeTo(ByteBuf byteBuf, LispTeRecord record) throws LispWriterException {
236
237 byteBuf.writeByte(UNUSED_ZERO);
238
239 // lookup flag
240 byte lookup = DISABLE_BIT;
241 if (record.isLookup()) {
242 lookup = (byte) (ENABLE_BIT << LOOKUP_FLAG_SHIFT_BIT);
243 }
244
245 // RLOC probe flag
246 byte rlocProbe = DISABLE_BIT;
247 if (record.isRlocProbe()) {
248 rlocProbe = (byte) (ENABLE_BIT << RLOC_PROBE_FLAG_SHIFT_BIT);
249 }
250
251 // strict flag
252 byte strict = DISABLE_BIT;
253 if (record.isStrict()) {
254 strict = (byte) (ENABLE_BIT << STRICT_FLAG_SHIFT_BIT);
255 }
256
257 byteBuf.writeByte((byte) (lookup + rlocProbe + strict));
258
259 // RTR RLOC address
Jian Li5e505c62016-12-05 02:44:24 +0900260 AfiAddressWriter writer = new AfiAddressWriter();
Jian Li99f83ef2016-11-03 19:14:25 +0100261 writer.writeTo(byteBuf, record.rtrRlocAddress);
262 }
263 }
264}