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