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