Committed by
Gerrit Code Review
[ONOS-4718] Initial implementation of LISP control msg deserializer
- Add LispLocatorRecord interface along with DefaultLispLocatorRecord class and unit test class - Add deserialization logic for four LISP control message classes and two auxiliary classes - Add ByteOperator utility to ease the bit access and manipulation for byte data type Change-Id: I68edf6877a0ebb52260296fc556e0690b795a845
Showing
20 changed files
with
976 additions
and
42 deletions
protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispLocatorRecord.java
0 → 100644
1 | +/* | ||
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 | + */ | ||
16 | +package org.onosproject.lisp.msg.protocols; | ||
17 | + | ||
18 | +import com.google.common.base.Objects; | ||
19 | +import io.netty.buffer.ByteBuf; | ||
20 | +import org.onlab.util.ByteOperator; | ||
21 | +import org.onosproject.lisp.msg.exceptions.LispParseError; | ||
22 | +import org.onosproject.lisp.msg.types.LispAfiAddress; | ||
23 | + | ||
24 | +import static com.google.common.base.MoreObjects.toStringHelper; | ||
25 | + | ||
26 | +/** | ||
27 | + * Default implementation of LispLocatorRecord. | ||
28 | + */ | ||
29 | +public final class DefaultLispLocatorRecord implements LispLocatorRecord { | ||
30 | + | ||
31 | + private final byte priority; | ||
32 | + private final byte weight; | ||
33 | + private final byte multicastPriority; | ||
34 | + private final byte multicastWeight; | ||
35 | + private final boolean localLocator; | ||
36 | + private final boolean rlocProbed; | ||
37 | + private final boolean routed; | ||
38 | + private final LispAfiAddress locatorAfi; | ||
39 | + | ||
40 | + /** | ||
41 | + * A private constructor that protects object instantiation from external. | ||
42 | + * | ||
43 | + * @param priority uni-cast priority | ||
44 | + * @param weight uni-cast weight | ||
45 | + * @param multicastPriority multi-cast priority | ||
46 | + * @param multicastWeight multi-cast weight | ||
47 | + * @param localLocator local locator flag | ||
48 | + * @param rlocProbed RLOC probed flag | ||
49 | + * @param routed routed flag | ||
50 | + * @param locatorAfi locator AFI | ||
51 | + */ | ||
52 | + private DefaultLispLocatorRecord(byte priority, byte weight, byte multicastPriority, | ||
53 | + byte multicastWeight, boolean localLocator, boolean rlocProbed, | ||
54 | + boolean routed, LispAfiAddress locatorAfi) { | ||
55 | + this.priority = priority; | ||
56 | + this.weight = weight; | ||
57 | + this.multicastPriority = multicastPriority; | ||
58 | + this.multicastWeight = multicastWeight; | ||
59 | + this.localLocator = localLocator; | ||
60 | + this.rlocProbed = rlocProbed; | ||
61 | + this.routed = routed; | ||
62 | + this.locatorAfi = locatorAfi; | ||
63 | + } | ||
64 | + | ||
65 | + @Override | ||
66 | + public byte getPriority() { | ||
67 | + return priority; | ||
68 | + } | ||
69 | + | ||
70 | + @Override | ||
71 | + public byte getWeight() { | ||
72 | + return weight; | ||
73 | + } | ||
74 | + | ||
75 | + @Override | ||
76 | + public byte getMulticastPriority() { | ||
77 | + return multicastPriority; | ||
78 | + } | ||
79 | + | ||
80 | + @Override | ||
81 | + public byte getMulticastWeight() { | ||
82 | + return multicastWeight; | ||
83 | + } | ||
84 | + | ||
85 | + @Override | ||
86 | + public boolean isLocalLocator() { | ||
87 | + return localLocator; | ||
88 | + } | ||
89 | + | ||
90 | + @Override | ||
91 | + public boolean isRlocProbed() { | ||
92 | + return rlocProbed; | ||
93 | + } | ||
94 | + | ||
95 | + @Override | ||
96 | + public boolean isRouted() { | ||
97 | + return routed; | ||
98 | + } | ||
99 | + | ||
100 | + @Override | ||
101 | + public LispAfiAddress getLocatorAfi() { | ||
102 | + return locatorAfi; | ||
103 | + } | ||
104 | + | ||
105 | + @Override | ||
106 | + public void writeTo(ByteBuf byteBuf) { | ||
107 | + | ||
108 | + } | ||
109 | + | ||
110 | + @Override | ||
111 | + public String toString() { | ||
112 | + return toStringHelper(this) | ||
113 | + .add("priority", priority) | ||
114 | + .add("weight", weight) | ||
115 | + .add("multi-cast priority", multicastPriority) | ||
116 | + .add("multi-cast weight", multicastWeight) | ||
117 | + .add("local locator", localLocator) | ||
118 | + .add("RLOC probed", rlocProbed) | ||
119 | + .add("routed", routed) | ||
120 | + .add("locator AFI", locatorAfi).toString(); | ||
121 | + } | ||
122 | + | ||
123 | + @Override | ||
124 | + public boolean equals(Object o) { | ||
125 | + if (this == o) { | ||
126 | + return true; | ||
127 | + } | ||
128 | + if (o == null || getClass() != o.getClass()) { | ||
129 | + return false; | ||
130 | + } | ||
131 | + DefaultLispLocatorRecord that = (DefaultLispLocatorRecord) o; | ||
132 | + return Objects.equal(priority, that.priority) && | ||
133 | + Objects.equal(weight, that.weight) && | ||
134 | + Objects.equal(multicastPriority, that.multicastPriority) && | ||
135 | + Objects.equal(multicastWeight, that.multicastWeight) && | ||
136 | + Objects.equal(localLocator, that.localLocator) && | ||
137 | + Objects.equal(rlocProbed, that.rlocProbed) && | ||
138 | + Objects.equal(routed, that.routed) && | ||
139 | + Objects.equal(locatorAfi, that.locatorAfi); | ||
140 | + } | ||
141 | + | ||
142 | + @Override | ||
143 | + public int hashCode() { | ||
144 | + return Objects.hashCode(priority, weight, multicastPriority, | ||
145 | + multicastWeight, localLocator, rlocProbed, routed, locatorAfi); | ||
146 | + } | ||
147 | + | ||
148 | + public static final class DefaultLocatorRecordBuilder implements LocatorRecordBuilder { | ||
149 | + | ||
150 | + private byte priority; | ||
151 | + private byte weight; | ||
152 | + private byte multicastPriority; | ||
153 | + private byte multicastWeight; | ||
154 | + private boolean localLocator; | ||
155 | + private boolean rlocProbed; | ||
156 | + private boolean routed; | ||
157 | + private LispAfiAddress locatorAfi; | ||
158 | + | ||
159 | + @Override | ||
160 | + public LocatorRecordBuilder withPriority(byte priority) { | ||
161 | + this.priority = priority; | ||
162 | + return this; | ||
163 | + } | ||
164 | + | ||
165 | + @Override | ||
166 | + public LocatorRecordBuilder withWeight(byte weight) { | ||
167 | + this.weight = weight; | ||
168 | + return this; | ||
169 | + } | ||
170 | + | ||
171 | + @Override | ||
172 | + public LocatorRecordBuilder withMulticastPriority(byte priority) { | ||
173 | + this.multicastPriority = priority; | ||
174 | + return this; | ||
175 | + } | ||
176 | + | ||
177 | + @Override | ||
178 | + public LocatorRecordBuilder withMulticastWeight(byte weight) { | ||
179 | + this.multicastWeight = weight; | ||
180 | + return this; | ||
181 | + } | ||
182 | + | ||
183 | + @Override | ||
184 | + public LocatorRecordBuilder withLocalLocator(boolean localLocator) { | ||
185 | + this.localLocator = localLocator; | ||
186 | + return this; | ||
187 | + } | ||
188 | + | ||
189 | + @Override | ||
190 | + public LocatorRecordBuilder withRlocProbed(boolean rlocProbed) { | ||
191 | + this.rlocProbed = rlocProbed; | ||
192 | + return this; | ||
193 | + } | ||
194 | + | ||
195 | + @Override | ||
196 | + public LocatorRecordBuilder withRouted(boolean routed) { | ||
197 | + this.routed = routed; | ||
198 | + return this; | ||
199 | + } | ||
200 | + | ||
201 | + @Override | ||
202 | + public LocatorRecordBuilder withLocatorAfi(LispAfiAddress locatorAfi) { | ||
203 | + this.locatorAfi = locatorAfi; | ||
204 | + return this; | ||
205 | + } | ||
206 | + | ||
207 | + @Override | ||
208 | + public LispLocatorRecord build() { | ||
209 | + return new DefaultLispLocatorRecord(priority, weight, multicastPriority, | ||
210 | + multicastWeight, localLocator, rlocProbed, routed, locatorAfi); | ||
211 | + } | ||
212 | + } | ||
213 | + | ||
214 | + /** | ||
215 | + * A LISP message reader for LocatorRecord portion. | ||
216 | + */ | ||
217 | + public static final class LocatorRecordReader implements LispMessageReader<LispLocatorRecord> { | ||
218 | + | ||
219 | + private static final int SKIP_UNUSED_FLAG_LENGTH = 1; | ||
220 | + private static final int LOCAL_LOCATOR_INDEX = 2; | ||
221 | + private static final int RLOC_PROBED_INDEX = 1; | ||
222 | + private static final int ROUTED_INDEX = 0; | ||
223 | + | ||
224 | + @Override | ||
225 | + public LispLocatorRecord readFrom(ByteBuf byteBuf) throws LispParseError { | ||
226 | + | ||
227 | + // priority -> 8 bits | ||
228 | + byte priority = (byte) byteBuf.readUnsignedByte(); | ||
229 | + | ||
230 | + // weight -> 8 bits | ||
231 | + byte weight = (byte) byteBuf.readUnsignedByte(); | ||
232 | + | ||
233 | + // multi-cast priority -> 8 bits | ||
234 | + byte multicastPriority = (byte) byteBuf.readUnsignedByte(); | ||
235 | + | ||
236 | + // multi-cast weight -> 8 bits | ||
237 | + byte multicastWeight = (byte) byteBuf.readUnsignedByte(); | ||
238 | + | ||
239 | + // let's skip unused flags | ||
240 | + byteBuf.skipBytes(SKIP_UNUSED_FLAG_LENGTH); | ||
241 | + | ||
242 | + byte flags = byteBuf.readByte(); | ||
243 | + | ||
244 | + // local locator flag -> 1 bit | ||
245 | + boolean localLocator = ByteOperator.getBit(flags, LOCAL_LOCATOR_INDEX); | ||
246 | + | ||
247 | + // rloc probe flag -> 1 bit | ||
248 | + boolean rlocProbed = ByteOperator.getBit(flags, RLOC_PROBED_INDEX); | ||
249 | + | ||
250 | + // routed flag -> 1 bit | ||
251 | + boolean routed = ByteOperator.getBit(flags, ROUTED_INDEX); | ||
252 | + | ||
253 | + // TODO: de-serialize ITR-RLOC AFI and address | ||
254 | + | ||
255 | + return new DefaultLocatorRecordBuilder() | ||
256 | + .withPriority(priority) | ||
257 | + .withWeight(weight) | ||
258 | + .withMulticastPriority(multicastPriority) | ||
259 | + .withMulticastWeight(multicastWeight) | ||
260 | + .withLocalLocator(localLocator) | ||
261 | + .withRlocProbed(rlocProbed) | ||
262 | + .withRouted(routed) | ||
263 | + .build(); | ||
264 | + } | ||
265 | + } | ||
266 | +} |
... | @@ -131,7 +131,7 @@ public final class DefaultLispMapNotify implements LispMapNotify { | ... | @@ -131,7 +131,7 @@ public final class DefaultLispMapNotify implements LispMapNotify { |
131 | private short keyId; | 131 | private short keyId; |
132 | private byte[] authenticationData; | 132 | private byte[] authenticationData; |
133 | private byte recordCount; | 133 | private byte recordCount; |
134 | - private List<LispMapRecord> mapRecords = Lists.newArrayList(); | 134 | + private List<LispMapRecord> mapRecords; |
135 | 135 | ||
136 | @Override | 136 | @Override |
137 | public LispType getType() { | 137 | public LispType getType() { |
... | @@ -163,8 +163,8 @@ public final class DefaultLispMapNotify implements LispMapNotify { | ... | @@ -163,8 +163,8 @@ public final class DefaultLispMapNotify implements LispMapNotify { |
163 | } | 163 | } |
164 | 164 | ||
165 | @Override | 165 | @Override |
166 | - public NotifyBuilder addRecord(LispMapRecord record) { | 166 | + public NotifyBuilder withMapRecords(List<LispMapRecord> mapRecords) { |
167 | - this.mapRecords.add(record); | 167 | + this.mapRecords = ImmutableList.copyOf(mapRecords); |
168 | return this; | 168 | return this; |
169 | } | 169 | } |
170 | 170 | ||
... | @@ -180,9 +180,46 @@ public final class DefaultLispMapNotify implements LispMapNotify { | ... | @@ -180,9 +180,46 @@ public final class DefaultLispMapNotify implements LispMapNotify { |
180 | */ | 180 | */ |
181 | private static class NotifyReader implements LispMessageReader<LispMapNotify> { | 181 | private static class NotifyReader implements LispMessageReader<LispMapNotify> { |
182 | 182 | ||
183 | + private static final int RESERVED_SKIP_LENGTH = 3; | ||
184 | + | ||
183 | @Override | 185 | @Override |
184 | public LispMapNotify readFrom(ByteBuf byteBuf) throws LispParseError { | 186 | public LispMapNotify readFrom(ByteBuf byteBuf) throws LispParseError { |
185 | - return null; | 187 | + |
188 | + if (byteBuf.readerIndex() != 0) { | ||
189 | + return null; | ||
190 | + } | ||
191 | + | ||
192 | + // skip first three bytes as they represent type and reserved fields | ||
193 | + byteBuf.skipBytes(RESERVED_SKIP_LENGTH); | ||
194 | + | ||
195 | + // record count -> 8 bits | ||
196 | + byte recordCount = (byte) byteBuf.readUnsignedByte(); | ||
197 | + | ||
198 | + // nonce -> 64 bits | ||
199 | + long nonce = byteBuf.readLong(); | ||
200 | + | ||
201 | + // keyId -> 16 bits | ||
202 | + short keyId = byteBuf.readShort(); | ||
203 | + | ||
204 | + // authenticationDataLength -> 16 bits | ||
205 | + short authLength = byteBuf.readShort(); | ||
206 | + | ||
207 | + // authenticationData -> depends on the authenticationDataLength | ||
208 | + byte[] authData = new byte[authLength]; | ||
209 | + byteBuf.readBytes(authData); | ||
210 | + | ||
211 | + List<LispMapRecord> mapRecords = Lists.newArrayList(); | ||
212 | + for (int i = 0; i < recordCount; i++) { | ||
213 | + mapRecords.add(new DefaultLispMapRecord.MapRecordReader().readFrom(byteBuf)); | ||
214 | + } | ||
215 | + | ||
216 | + return new DefaultNotifyBuilder() | ||
217 | + .withRecordCount(recordCount) | ||
218 | + .withNonce(nonce) | ||
219 | + .withKeyId(keyId) | ||
220 | + .withAuthenticationData(authData) | ||
221 | + .withMapRecords(mapRecords) | ||
222 | + .build(); | ||
186 | } | 223 | } |
187 | } | 224 | } |
188 | } | 225 | } | ... | ... |
... | @@ -16,10 +16,15 @@ | ... | @@ -16,10 +16,15 @@ |
16 | package org.onosproject.lisp.msg.protocols; | 16 | package org.onosproject.lisp.msg.protocols; |
17 | 17 | ||
18 | import com.google.common.base.Objects; | 18 | import com.google.common.base.Objects; |
19 | +import com.google.common.collect.ImmutableList; | ||
20 | +import com.google.common.collect.Lists; | ||
19 | import io.netty.buffer.ByteBuf; | 21 | import io.netty.buffer.ByteBuf; |
22 | +import org.onlab.util.ByteOperator; | ||
20 | import org.onosproject.lisp.msg.exceptions.LispParseError; | 23 | import org.onosproject.lisp.msg.exceptions.LispParseError; |
21 | import org.onosproject.lisp.msg.types.LispAfiAddress; | 24 | import org.onosproject.lisp.msg.types.LispAfiAddress; |
22 | 25 | ||
26 | +import java.util.List; | ||
27 | + | ||
23 | import static com.google.common.base.MoreObjects.toStringHelper; | 28 | import static com.google.common.base.MoreObjects.toStringHelper; |
24 | 29 | ||
25 | /** | 30 | /** |
... | @@ -34,6 +39,7 @@ public final class DefaultLispMapRecord implements LispMapRecord { | ... | @@ -34,6 +39,7 @@ public final class DefaultLispMapRecord implements LispMapRecord { |
34 | private final boolean authoritative; | 39 | private final boolean authoritative; |
35 | private final short mapVersionNumber; | 40 | private final short mapVersionNumber; |
36 | private final LispAfiAddress eidPrefixAfi; | 41 | private final LispAfiAddress eidPrefixAfi; |
42 | + private final List<LispLocatorRecord> locatorRecords; | ||
37 | 43 | ||
38 | /** | 44 | /** |
39 | * A private constructor that protects object instantiation from external. | 45 | * A private constructor that protects object instantiation from external. |
... | @@ -48,7 +54,8 @@ public final class DefaultLispMapRecord implements LispMapRecord { | ... | @@ -48,7 +54,8 @@ public final class DefaultLispMapRecord implements LispMapRecord { |
48 | */ | 54 | */ |
49 | private DefaultLispMapRecord(int recordTtl, int locatorCount, byte maskLength, | 55 | private DefaultLispMapRecord(int recordTtl, int locatorCount, byte maskLength, |
50 | LispMapReplyAction action, boolean authoritative, | 56 | LispMapReplyAction action, boolean authoritative, |
51 | - short mapVersionNumber, LispAfiAddress eidPrefixAfi) { | 57 | + short mapVersionNumber, LispAfiAddress eidPrefixAfi, |
58 | + List<LispLocatorRecord> locatorRecords) { | ||
52 | this.recordTtl = recordTtl; | 59 | this.recordTtl = recordTtl; |
53 | this.locatorCount = locatorCount; | 60 | this.locatorCount = locatorCount; |
54 | this.maskLength = maskLength; | 61 | this.maskLength = maskLength; |
... | @@ -56,6 +63,7 @@ public final class DefaultLispMapRecord implements LispMapRecord { | ... | @@ -56,6 +63,7 @@ public final class DefaultLispMapRecord implements LispMapRecord { |
56 | this.authoritative = authoritative; | 63 | this.authoritative = authoritative; |
57 | this.mapVersionNumber = mapVersionNumber; | 64 | this.mapVersionNumber = mapVersionNumber; |
58 | this.eidPrefixAfi = eidPrefixAfi; | 65 | this.eidPrefixAfi = eidPrefixAfi; |
66 | + this.locatorRecords = locatorRecords; | ||
59 | } | 67 | } |
60 | 68 | ||
61 | @Override | 69 | @Override |
... | @@ -94,6 +102,16 @@ public final class DefaultLispMapRecord implements LispMapRecord { | ... | @@ -94,6 +102,16 @@ public final class DefaultLispMapRecord implements LispMapRecord { |
94 | } | 102 | } |
95 | 103 | ||
96 | @Override | 104 | @Override |
105 | + public List<LispLocatorRecord> getLocators() { | ||
106 | + return ImmutableList.copyOf(locatorRecords); | ||
107 | + } | ||
108 | + | ||
109 | + @Override | ||
110 | + public void writeTo(ByteBuf byteBuf) { | ||
111 | + | ||
112 | + } | ||
113 | + | ||
114 | + @Override | ||
97 | public String toString() { | 115 | public String toString() { |
98 | return toStringHelper(this) | 116 | return toStringHelper(this) |
99 | .add("record TTL", recordTtl) | 117 | .add("record TTL", recordTtl) |
... | @@ -102,7 +120,9 @@ public final class DefaultLispMapRecord implements LispMapRecord { | ... | @@ -102,7 +120,9 @@ public final class DefaultLispMapRecord implements LispMapRecord { |
102 | .add("action", action) | 120 | .add("action", action) |
103 | .add("authoritative", authoritative) | 121 | .add("authoritative", authoritative) |
104 | .add("mapVersionNumber", mapVersionNumber) | 122 | .add("mapVersionNumber", mapVersionNumber) |
105 | - .add("EID prefix AFI address", eidPrefixAfi).toString(); | 123 | + .add("EID prefix AFI address", eidPrefixAfi) |
124 | + .add("locator records", locatorRecords).toString(); | ||
125 | + | ||
106 | } | 126 | } |
107 | 127 | ||
108 | @Override | 128 | @Override |
... | @@ -120,13 +140,14 @@ public final class DefaultLispMapRecord implements LispMapRecord { | ... | @@ -120,13 +140,14 @@ public final class DefaultLispMapRecord implements LispMapRecord { |
120 | Objects.equal(action, that.action) && | 140 | Objects.equal(action, that.action) && |
121 | Objects.equal(authoritative, that.authoritative) && | 141 | Objects.equal(authoritative, that.authoritative) && |
122 | Objects.equal(mapVersionNumber, that.mapVersionNumber) && | 142 | Objects.equal(mapVersionNumber, that.mapVersionNumber) && |
123 | - Objects.equal(eidPrefixAfi, that.eidPrefixAfi); | 143 | + Objects.equal(eidPrefixAfi, that.eidPrefixAfi) && |
144 | + Objects.equal(locatorRecords, that.locatorRecords); | ||
124 | } | 145 | } |
125 | 146 | ||
126 | @Override | 147 | @Override |
127 | public int hashCode() { | 148 | public int hashCode() { |
128 | return Objects.hashCode(recordTtl, locatorCount, maskLength, action, | 149 | return Objects.hashCode(recordTtl, locatorCount, maskLength, action, |
129 | - authoritative, mapVersionNumber, eidPrefixAfi); | 150 | + authoritative, mapVersionNumber, eidPrefixAfi, locatorRecords); |
130 | } | 151 | } |
131 | 152 | ||
132 | public static final class DefaultMapRecordBuilder implements MapRecordBuilder { | 153 | public static final class DefaultMapRecordBuilder implements MapRecordBuilder { |
... | @@ -138,6 +159,7 @@ public final class DefaultLispMapRecord implements LispMapRecord { | ... | @@ -138,6 +159,7 @@ public final class DefaultLispMapRecord implements LispMapRecord { |
138 | private boolean authoritative; | 159 | private boolean authoritative; |
139 | private short mapVersionNumber; | 160 | private short mapVersionNumber; |
140 | private LispAfiAddress eidPrefixAfi; | 161 | private LispAfiAddress eidPrefixAfi; |
162 | + private List<LispLocatorRecord> locatorRecords; | ||
141 | 163 | ||
142 | @Override | 164 | @Override |
143 | public MapRecordBuilder withRecordTtl(int recordTtl) { | 165 | public MapRecordBuilder withRecordTtl(int recordTtl) { |
... | @@ -182,20 +204,66 @@ public final class DefaultLispMapRecord implements LispMapRecord { | ... | @@ -182,20 +204,66 @@ public final class DefaultLispMapRecord implements LispMapRecord { |
182 | } | 204 | } |
183 | 205 | ||
184 | @Override | 206 | @Override |
207 | + public MapRecordBuilder withLocators(List<LispLocatorRecord> records) { | ||
208 | + this.locatorRecords = ImmutableList.copyOf(records); | ||
209 | + return this; | ||
210 | + } | ||
211 | + | ||
212 | + @Override | ||
185 | public LispMapRecord build() { | 213 | public LispMapRecord build() { |
186 | return new DefaultLispMapRecord(recordTtl, locatorCount, maskLength, | 214 | return new DefaultLispMapRecord(recordTtl, locatorCount, maskLength, |
187 | - action, authoritative, mapVersionNumber, eidPrefixAfi); | 215 | + action, authoritative, mapVersionNumber, eidPrefixAfi, locatorRecords); |
188 | } | 216 | } |
189 | } | 217 | } |
190 | 218 | ||
191 | /** | 219 | /** |
192 | - * A private LISP message reader for MapRecord portion. | 220 | + * A LISP message reader for MapRecord portion. |
193 | */ | 221 | */ |
194 | - private static class RecordReader implements LispMessageReader<LispMapRecord> { | 222 | + public static final class MapRecordReader implements LispMessageReader<LispMapRecord> { |
223 | + | ||
224 | + private static final int AUTHORITATIVE_INDEX = 4; | ||
225 | + private static final int RESERVED_SKIP_LENGTH = 1; | ||
195 | 226 | ||
196 | @Override | 227 | @Override |
197 | public LispMapRecord readFrom(ByteBuf byteBuf) throws LispParseError { | 228 | public LispMapRecord readFrom(ByteBuf byteBuf) throws LispParseError { |
198 | - return null; | 229 | + |
230 | + // Record TTL -> 32 bits | ||
231 | + int recordTtl = byteBuf.readInt(); | ||
232 | + | ||
233 | + // Locator count -> 8 bits | ||
234 | + int locatorCount = byteBuf.readUnsignedShort(); | ||
235 | + | ||
236 | + // EID mask length -> 8 bits | ||
237 | + byte maskLength = (byte) byteBuf.readUnsignedByte(); | ||
238 | + | ||
239 | + // TODO: need to de-serialize LispMapReplyAction | ||
240 | + | ||
241 | + byte actionWithFlag = byteBuf.readByte(); | ||
242 | + | ||
243 | + // authoritative flag -> 1 bit | ||
244 | + boolean authoritative = ByteOperator.getBit(actionWithFlag, AUTHORITATIVE_INDEX); | ||
245 | + | ||
246 | + // let's skip the reserved field | ||
247 | + byteBuf.skipBytes(RESERVED_SKIP_LENGTH); | ||
248 | + | ||
249 | + // Map version number -> 12 bits, we treat Rsvd field is all zero | ||
250 | + short mapVersionNumber = (short) byteBuf.readUnsignedShort(); | ||
251 | + | ||
252 | + // TODO: need to de-serialize EID AFI address | ||
253 | + | ||
254 | + List<LispLocatorRecord> locators = Lists.newArrayList(); | ||
255 | + for (int i = 0; i < locatorCount; i++) { | ||
256 | + locators.add(new DefaultLispLocatorRecord.LocatorRecordReader().readFrom(byteBuf)); | ||
257 | + } | ||
258 | + | ||
259 | + return new DefaultMapRecordBuilder() | ||
260 | + .withRecordTtl(recordTtl) | ||
261 | + .withLocatorCount(locatorCount) | ||
262 | + .withMaskLength(maskLength) | ||
263 | + .withAuthoritative(authoritative) | ||
264 | + .withMapVersionNumber(mapVersionNumber) | ||
265 | + .withLocators(locators) | ||
266 | + .build(); | ||
199 | } | 267 | } |
200 | } | 268 | } |
201 | } | 269 | } | ... | ... |
... | @@ -19,6 +19,7 @@ import com.google.common.base.Objects; | ... | @@ -19,6 +19,7 @@ import com.google.common.base.Objects; |
19 | import com.google.common.collect.ImmutableList; | 19 | import com.google.common.collect.ImmutableList; |
20 | import com.google.common.collect.Lists; | 20 | import com.google.common.collect.Lists; |
21 | import io.netty.buffer.ByteBuf; | 21 | import io.netty.buffer.ByteBuf; |
22 | +import org.onlab.util.ByteOperator; | ||
22 | import org.onlab.util.ImmutableByteSequence; | 23 | import org.onlab.util.ImmutableByteSequence; |
23 | import org.onosproject.lisp.msg.exceptions.LispParseError; | 24 | import org.onosproject.lisp.msg.exceptions.LispParseError; |
24 | 25 | ||
... | @@ -155,7 +156,7 @@ public final class DefaultLispMapRegister implements LispMapRegister { | ... | @@ -155,7 +156,7 @@ public final class DefaultLispMapRegister implements LispMapRegister { |
155 | private short keyId; | 156 | private short keyId; |
156 | private byte[] authenticationData; | 157 | private byte[] authenticationData; |
157 | private byte recordCount; | 158 | private byte recordCount; |
158 | - private final List<LispMapRecord> mapRecords = Lists.newArrayList(); | 159 | + private List<LispMapRecord> mapRecords; |
159 | private boolean proxyMapReply; | 160 | private boolean proxyMapReply; |
160 | private boolean wantMapNotify; | 161 | private boolean wantMapNotify; |
161 | 162 | ||
... | @@ -201,8 +202,8 @@ public final class DefaultLispMapRegister implements LispMapRegister { | ... | @@ -201,8 +202,8 @@ public final class DefaultLispMapRegister implements LispMapRegister { |
201 | } | 202 | } |
202 | 203 | ||
203 | @Override | 204 | @Override |
204 | - public RegisterBuilder addRecord(LispMapRecord record) { | 205 | + public RegisterBuilder withMapRecords(List<LispMapRecord> mapRecords) { |
205 | - this.mapRecords.add(record); | 206 | + this.mapRecords = ImmutableList.copyOf(mapRecords); |
206 | return this; | 207 | return this; |
207 | } | 208 | } |
208 | 209 | ||
... | @@ -218,9 +219,58 @@ public final class DefaultLispMapRegister implements LispMapRegister { | ... | @@ -218,9 +219,58 @@ public final class DefaultLispMapRegister implements LispMapRegister { |
218 | */ | 219 | */ |
219 | private static class RegisterReader implements LispMessageReader<LispMapRegister> { | 220 | private static class RegisterReader implements LispMessageReader<LispMapRegister> { |
220 | 221 | ||
222 | + private static final int PROXY_MAP_REPLY_INDEX = 3; | ||
223 | + private static final int WANT_MAP_NOTIFY_INDEX = 0; | ||
224 | + private static final int RESERVED_SKIP_LENGTH = 1; | ||
225 | + | ||
221 | @Override | 226 | @Override |
222 | public LispMapRegister readFrom(ByteBuf byteBuf) throws LispParseError { | 227 | public LispMapRegister readFrom(ByteBuf byteBuf) throws LispParseError { |
223 | - return null; | 228 | + |
229 | + if (byteBuf.readerIndex() != 0) { | ||
230 | + return null; | ||
231 | + } | ||
232 | + | ||
233 | + // proxyMapReply -> 1 bit | ||
234 | + boolean proxyMapReplyFlag = ByteOperator.getBit(byteBuf.readByte(), PROXY_MAP_REPLY_INDEX); | ||
235 | + | ||
236 | + // let's skip the reserved field | ||
237 | + byteBuf.skipBytes(RESERVED_SKIP_LENGTH); | ||
238 | + | ||
239 | + byte reservedWithFlag = byteBuf.readByte(); | ||
240 | + | ||
241 | + // wantMapReply -> 1 bit | ||
242 | + boolean wantMapNotifyFlag = ByteOperator.getBit(reservedWithFlag, WANT_MAP_NOTIFY_INDEX); | ||
243 | + | ||
244 | + // record count -> 8 bits | ||
245 | + byte recordCount = (byte) byteBuf.readUnsignedByte(); | ||
246 | + | ||
247 | + // nonce -> 64 bits | ||
248 | + long nonce = byteBuf.readLong(); | ||
249 | + | ||
250 | + // keyId -> 16 bits | ||
251 | + short keyId = byteBuf.readShort(); | ||
252 | + | ||
253 | + // authenticationDataLength -> 16 bits | ||
254 | + short authLength = byteBuf.readShort(); | ||
255 | + | ||
256 | + // authenticationData -> depends on the authenticationDataLength | ||
257 | + byte[] authData = new byte[authLength]; | ||
258 | + byteBuf.readBytes(authData); | ||
259 | + | ||
260 | + List<LispMapRecord> mapRecords = Lists.newArrayList(); | ||
261 | + for (int i = 0; i < recordCount; i++) { | ||
262 | + mapRecords.add(new DefaultLispMapRecord.MapRecordReader().readFrom(byteBuf)); | ||
263 | + } | ||
264 | + | ||
265 | + return new DefaultRegisterBuilder() | ||
266 | + .withIsProxyMapReply(proxyMapReplyFlag) | ||
267 | + .withIsWantMapNotify(wantMapNotifyFlag) | ||
268 | + .withRecordCount(recordCount) | ||
269 | + .withNonce(nonce) | ||
270 | + .withKeyId(keyId) | ||
271 | + .withAuthenticationData(authData) | ||
272 | + .withMapRecords(mapRecords) | ||
273 | + .build(); | ||
224 | } | 274 | } |
225 | } | 275 | } |
226 | } | 276 | } | ... | ... |
... | @@ -17,6 +17,7 @@ package org.onosproject.lisp.msg.protocols; | ... | @@ -17,6 +17,7 @@ package org.onosproject.lisp.msg.protocols; |
17 | 17 | ||
18 | import com.google.common.base.Objects; | 18 | import com.google.common.base.Objects; |
19 | import io.netty.buffer.ByteBuf; | 19 | import io.netty.buffer.ByteBuf; |
20 | +import org.onlab.util.ByteOperator; | ||
20 | import org.onosproject.lisp.msg.exceptions.LispParseError; | 21 | import org.onosproject.lisp.msg.exceptions.LispParseError; |
21 | 22 | ||
22 | import static com.google.common.base.MoreObjects.toStringHelper; | 23 | import static com.google.common.base.MoreObjects.toStringHelper; |
... | @@ -176,9 +177,47 @@ public final class DefaultLispMapReply implements LispMapReply { | ... | @@ -176,9 +177,47 @@ public final class DefaultLispMapReply implements LispMapReply { |
176 | */ | 177 | */ |
177 | private static class ReplyReader implements LispMessageReader<LispMapReply> { | 178 | private static class ReplyReader implements LispMessageReader<LispMapReply> { |
178 | 179 | ||
180 | + private static final int PROBE_INDEX = 3; | ||
181 | + private static final int ETR_INDEX = 2; | ||
182 | + private static final int SECURITY_INDEX = 1; | ||
183 | + private static final int RESERVED_SKIP_LENGTH = 2; | ||
184 | + | ||
179 | @Override | 185 | @Override |
180 | public LispMapReply readFrom(ByteBuf byteBuf) throws LispParseError { | 186 | public LispMapReply readFrom(ByteBuf byteBuf) throws LispParseError { |
181 | - return null; | 187 | + |
188 | + if (byteBuf.readerIndex() != 0) { | ||
189 | + return null; | ||
190 | + } | ||
191 | + | ||
192 | + byte typeWithFlags = byteBuf.readByte(); | ||
193 | + | ||
194 | + // probe -> 1 bit | ||
195 | + boolean probe = ByteOperator.getBit(typeWithFlags, PROBE_INDEX); | ||
196 | + | ||
197 | + // etr -> 1bit | ||
198 | + boolean etr = ByteOperator.getBit(typeWithFlags, ETR_INDEX); | ||
199 | + | ||
200 | + // security -> 1 bit | ||
201 | + boolean security = ByteOperator.getBit(typeWithFlags, SECURITY_INDEX); | ||
202 | + | ||
203 | + // skip two bytes as they represent reserved fields | ||
204 | + byteBuf.skipBytes(RESERVED_SKIP_LENGTH); | ||
205 | + | ||
206 | + // record count -> 8 bits | ||
207 | + byte recordCount = (byte) byteBuf.readUnsignedByte(); | ||
208 | + | ||
209 | + // nonce -> 64 bits | ||
210 | + long nonce = byteBuf.readLong(); | ||
211 | + | ||
212 | + // TODO: need to de-serialize EID-RLOC records | ||
213 | + | ||
214 | + return new DefaultReplyBuilder() | ||
215 | + .withIsProbe(probe) | ||
216 | + .withIsEtr(etr) | ||
217 | + .withIsSecurity(security) | ||
218 | + .withRecordCount(recordCount) | ||
219 | + .withNonce(nonce) | ||
220 | + .build(); | ||
182 | } | 221 | } |
183 | } | 222 | } |
184 | } | 223 | } | ... | ... |
... | @@ -19,6 +19,7 @@ import com.google.common.base.Objects; | ... | @@ -19,6 +19,7 @@ import com.google.common.base.Objects; |
19 | import com.google.common.collect.ImmutableList; | 19 | import com.google.common.collect.ImmutableList; |
20 | import com.google.common.collect.Lists; | 20 | import com.google.common.collect.Lists; |
21 | import io.netty.buffer.ByteBuf; | 21 | import io.netty.buffer.ByteBuf; |
22 | +import org.onlab.util.ByteOperator; | ||
22 | import org.onosproject.lisp.msg.exceptions.LispParseError; | 23 | import org.onosproject.lisp.msg.exceptions.LispParseError; |
23 | import org.onosproject.lisp.msg.types.LispAfiAddress; | 24 | import org.onosproject.lisp.msg.types.LispAfiAddress; |
24 | 25 | ||
... | @@ -227,7 +228,6 @@ public final class DefaultLispMapRequest implements LispMapRequest { | ... | @@ -227,7 +228,6 @@ public final class DefaultLispMapRequest implements LispMapRequest { |
227 | return this; | 228 | return this; |
228 | } | 229 | } |
229 | 230 | ||
230 | - | ||
231 | @Override | 231 | @Override |
232 | public RequestBuilder withIsSmr(boolean smr) { | 232 | public RequestBuilder withIsSmr(boolean smr) { |
233 | this.smr = smr; | 233 | this.smr = smr; |
... | @@ -265,14 +265,14 @@ public final class DefaultLispMapRequest implements LispMapRequest { | ... | @@ -265,14 +265,14 @@ public final class DefaultLispMapRequest implements LispMapRequest { |
265 | } | 265 | } |
266 | 266 | ||
267 | @Override | 267 | @Override |
268 | - public RequestBuilder addItrRloc(LispAfiAddress itrRloc) { | 268 | + public RequestBuilder withItrRlocs(List<LispAfiAddress> itrRlocs) { |
269 | - this.itrRlocs.add(itrRloc); | 269 | + this.itrRlocs = ImmutableList.copyOf(itrRlocs); |
270 | return this; | 270 | return this; |
271 | } | 271 | } |
272 | 272 | ||
273 | @Override | 273 | @Override |
274 | - public RequestBuilder addEidRecord(LispEidRecord record) { | 274 | + public RequestBuilder withEidRecords(List<LispEidRecord> records) { |
275 | - this.eidRecords.add(record); | 275 | + this.eidRecords = ImmutableList.copyOf(records); |
276 | return this; | 276 | return this; |
277 | } | 277 | } |
278 | 278 | ||
... | @@ -288,9 +288,69 @@ public final class DefaultLispMapRequest implements LispMapRequest { | ... | @@ -288,9 +288,69 @@ public final class DefaultLispMapRequest implements LispMapRequest { |
288 | */ | 288 | */ |
289 | private static class RequestReader implements LispMessageReader<LispMapRequest> { | 289 | private static class RequestReader implements LispMessageReader<LispMapRequest> { |
290 | 290 | ||
291 | + private static final int AUTHORITATIVE_INDEX = 3; | ||
292 | + private static final int MAP_DATA_PRESENT_INDEX = 2; | ||
293 | + private static final int PROBE_INDEX = 1; | ||
294 | + private static final int SMR_INDEX = 0; | ||
295 | + private static final int PITR_INDEX = 7; | ||
296 | + private static final int SMR_INVOKED_INDEX = 6; | ||
297 | + | ||
291 | @Override | 298 | @Override |
292 | public LispMapRequest readFrom(ByteBuf byteBuf) throws LispParseError { | 299 | public LispMapRequest readFrom(ByteBuf byteBuf) throws LispParseError { |
293 | - return null; | 300 | + |
301 | + if (byteBuf.readerIndex() != 0) { | ||
302 | + return null; | ||
303 | + } | ||
304 | + | ||
305 | + byte typeWithFlags = byteBuf.readByte(); | ||
306 | + | ||
307 | + // authoritative -> 1 bit | ||
308 | + boolean authoritative = ByteOperator.getBit(typeWithFlags, AUTHORITATIVE_INDEX); | ||
309 | + | ||
310 | + // mapDataPresent -> 1 bit | ||
311 | + boolean mapDataPresent = ByteOperator.getBit(typeWithFlags, MAP_DATA_PRESENT_INDEX); | ||
312 | + | ||
313 | + // probe -> 1 bit | ||
314 | + boolean probe = ByteOperator.getBit(typeWithFlags, PROBE_INDEX); | ||
315 | + | ||
316 | + // smr -> 1 bit | ||
317 | + boolean smr = ByteOperator.getBit(typeWithFlags, SMR_INDEX); | ||
318 | + | ||
319 | + byte reservedWithFlags = byteBuf.readByte(); | ||
320 | + | ||
321 | + // pitr -> 1 bit | ||
322 | + boolean pitr = ByteOperator.getBit(reservedWithFlags, PITR_INDEX); | ||
323 | + | ||
324 | + // smrInvoked -> 1 bit | ||
325 | + boolean smrInvoked = ByteOperator.getBit(reservedWithFlags, SMR_INVOKED_INDEX); | ||
326 | + | ||
327 | + // let's skip reserved field, only obtains ITR counter value | ||
328 | + // assume that first 3 bits are all set as 0, | ||
329 | + // remain 5 bits represent Itr Rloc Counter (IRC) | ||
330 | + int irc = byteBuf.readUnsignedShort(); | ||
331 | + | ||
332 | + // record count -> 8 bits | ||
333 | + int recordCount = byteBuf.readUnsignedShort(); | ||
334 | + | ||
335 | + // nonce -> 64 bits | ||
336 | + long nonce = byteBuf.readLong(); | ||
337 | + | ||
338 | + // TODO: de-serialize source EID AFI and address | ||
339 | + | ||
340 | + // TODO: de-serialize ITR-RLOC AFI and address | ||
341 | + | ||
342 | + // TODO: de-serialize EID-RECORD | ||
343 | + | ||
344 | + return new DefaultRequestBuilder() | ||
345 | + .withIsAuthoritative(authoritative) | ||
346 | + .withIsMapDataPresent(mapDataPresent) | ||
347 | + .withIsProbe(probe) | ||
348 | + .withIsSmr(smr) | ||
349 | + .withIsPitr(pitr) | ||
350 | + .withIsSmrInvoked(smrInvoked) | ||
351 | + .withNonce(nonce) | ||
352 | + .withRecordCount((byte) recordCount) | ||
353 | + .build(); | ||
294 | } | 354 | } |
295 | } | 355 | } |
296 | } | 356 | } | ... | ... |
... | @@ -61,9 +61,20 @@ public final class LispEidRecord { | ... | @@ -61,9 +61,20 @@ public final class LispEidRecord { |
61 | */ | 61 | */ |
62 | private static class EidRecordReader implements LispMessageReader<LispEidRecord> { | 62 | private static class EidRecordReader implements LispMessageReader<LispEidRecord> { |
63 | 63 | ||
64 | + private static final int RESERVED_SKIP_LENGTH = 1; | ||
65 | + | ||
64 | @Override | 66 | @Override |
65 | public LispEidRecord readFrom(ByteBuf byteBuf) throws LispParseError { | 67 | public LispEidRecord readFrom(ByteBuf byteBuf) throws LispParseError { |
66 | - return null; | 68 | + |
69 | + // let's skip the reserved field | ||
70 | + byteBuf.skipBytes(RESERVED_SKIP_LENGTH); | ||
71 | + | ||
72 | + short maskLength = (short) byteBuf.readUnsignedShort(); | ||
73 | + | ||
74 | + // TODO: need to de-serialize AFI address | ||
75 | + LispAfiAddress prefix = null; | ||
76 | + | ||
77 | + return new LispEidRecord((byte) maskLength, prefix); | ||
67 | } | 78 | } |
68 | } | 79 | } |
69 | } | 80 | } | ... | ... |
protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispLocatorRecord.java
0 → 100644
1 | +/* | ||
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 | + */ | ||
16 | +package org.onosproject.lisp.msg.protocols; | ||
17 | + | ||
18 | +import io.netty.buffer.ByteBuf; | ||
19 | +import org.onosproject.lisp.msg.types.LispAfiAddress; | ||
20 | + | ||
21 | +/** | ||
22 | + * LISP locator record section which is part of LISP map record. | ||
23 | + */ | ||
24 | +public interface LispLocatorRecord { | ||
25 | + | ||
26 | + /** | ||
27 | + * Obtains priority value. | ||
28 | + * | ||
29 | + * @return priority value | ||
30 | + */ | ||
31 | + byte getPriority(); | ||
32 | + | ||
33 | + /** | ||
34 | + * Obtains weight value. | ||
35 | + * | ||
36 | + * @return weight value | ||
37 | + */ | ||
38 | + byte getWeight(); | ||
39 | + | ||
40 | + /** | ||
41 | + * Obtains multi-cast priority value. | ||
42 | + * | ||
43 | + * @return multi-cast priority value | ||
44 | + */ | ||
45 | + byte getMulticastPriority(); | ||
46 | + | ||
47 | + /** | ||
48 | + * Obtains multi-cast weight value. | ||
49 | + * | ||
50 | + * @return multi-cast weight value | ||
51 | + */ | ||
52 | + byte getMulticastWeight(); | ||
53 | + | ||
54 | + /** | ||
55 | + * Obtains local locator flag. | ||
56 | + * | ||
57 | + * @return local locator flag | ||
58 | + */ | ||
59 | + boolean isLocalLocator(); | ||
60 | + | ||
61 | + /** | ||
62 | + * Obtains RLOC probed flag. | ||
63 | + * | ||
64 | + * @return RLOC probed flag | ||
65 | + */ | ||
66 | + boolean isRlocProbed(); | ||
67 | + | ||
68 | + /** | ||
69 | + * Obtains routed flag. | ||
70 | + * | ||
71 | + * @return routed flag | ||
72 | + */ | ||
73 | + boolean isRouted(); | ||
74 | + | ||
75 | + /** | ||
76 | + * Obtains locator AFI. | ||
77 | + * | ||
78 | + * @return locator AFI | ||
79 | + */ | ||
80 | + LispAfiAddress getLocatorAfi(); | ||
81 | + | ||
82 | + /** | ||
83 | + * Writes LISP message object into communication channel. | ||
84 | + * | ||
85 | + * @param byteBuf byte buffer | ||
86 | + */ | ||
87 | + void writeTo(ByteBuf byteBuf); | ||
88 | + | ||
89 | + /** | ||
90 | + * A builder of LISP locator record. | ||
91 | + */ | ||
92 | + interface LocatorRecordBuilder { | ||
93 | + | ||
94 | + /** | ||
95 | + * Sets priority value. | ||
96 | + * | ||
97 | + * @param priority priority | ||
98 | + * @return LocatorRecordBuilder object | ||
99 | + */ | ||
100 | + LocatorRecordBuilder withPriority(byte priority); | ||
101 | + | ||
102 | + /** | ||
103 | + * Sets weight value. | ||
104 | + * | ||
105 | + * @param weight weight | ||
106 | + * @return LocatorRecordBuilder object | ||
107 | + */ | ||
108 | + LocatorRecordBuilder withWeight(byte weight); | ||
109 | + | ||
110 | + /** | ||
111 | + * Sets multi-cast priority value. | ||
112 | + * | ||
113 | + * @param priority priority | ||
114 | + * @return LocatorRecordBuilder object | ||
115 | + */ | ||
116 | + LocatorRecordBuilder withMulticastPriority(byte priority); | ||
117 | + | ||
118 | + /** | ||
119 | + * Sets multi-cast weight value. | ||
120 | + * | ||
121 | + * @param weight weight | ||
122 | + * @return LocatorRecordBuilder object | ||
123 | + */ | ||
124 | + LocatorRecordBuilder withMulticastWeight(byte weight); | ||
125 | + | ||
126 | + /** | ||
127 | + * Sets local locator flag. | ||
128 | + * | ||
129 | + * @param localLocator local locator flag | ||
130 | + * @return LocatorRecordBuilder object | ||
131 | + */ | ||
132 | + LocatorRecordBuilder withLocalLocator(boolean localLocator); | ||
133 | + | ||
134 | + /** | ||
135 | + * Sets RLOC probed flag. | ||
136 | + * | ||
137 | + * @param rlocProbed RLOC probed flag | ||
138 | + * @return LocatorRecordBuilder object | ||
139 | + */ | ||
140 | + LocatorRecordBuilder withRlocProbed(boolean rlocProbed); | ||
141 | + | ||
142 | + /** | ||
143 | + * Sets routed flag. | ||
144 | + * | ||
145 | + * @param routed routed flag | ||
146 | + * @return LocatorRecordBuilder object | ||
147 | + */ | ||
148 | + LocatorRecordBuilder withRouted(boolean routed); | ||
149 | + | ||
150 | + /** | ||
151 | + * Sets locator AFI. | ||
152 | + * | ||
153 | + * @param locatorAfi locator AFI | ||
154 | + * @return LocatorRecordBuilder object | ||
155 | + */ | ||
156 | + LocatorRecordBuilder withLocatorAfi(LispAfiAddress locatorAfi); | ||
157 | + | ||
158 | + /** | ||
159 | + * Builds locator record. | ||
160 | + * | ||
161 | + * @return locator record instance | ||
162 | + */ | ||
163 | + LispLocatorRecord build(); | ||
164 | + } | ||
165 | +} |
... | @@ -129,12 +129,12 @@ public interface LispMapNotify extends LispMessage { | ... | @@ -129,12 +129,12 @@ public interface LispMapNotify extends LispMessage { |
129 | NotifyBuilder withAuthenticationData(byte[] authenticationData); | 129 | NotifyBuilder withAuthenticationData(byte[] authenticationData); |
130 | 130 | ||
131 | /** | 131 | /** |
132 | - * Adds a new record to record list. | 132 | + * Sets a collection of map records. |
133 | * | 133 | * |
134 | - * @param record record | 134 | + * @param mapRecords a collection of map records |
135 | - * @return NotifyBuilder object | 135 | + * @return RegisterBuilder object |
136 | */ | 136 | */ |
137 | - NotifyBuilder addRecord(LispMapRecord record); | 137 | + NotifyBuilder withMapRecords(List<LispMapRecord> mapRecords); |
138 | 138 | ||
139 | /** | 139 | /** |
140 | * Builds LISP map notify message. | 140 | * Builds LISP map notify message. | ... | ... |
... | @@ -15,8 +15,11 @@ | ... | @@ -15,8 +15,11 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.lisp.msg.protocols; | 16 | package org.onosproject.lisp.msg.protocols; |
17 | 17 | ||
18 | +import io.netty.buffer.ByteBuf; | ||
18 | import org.onosproject.lisp.msg.types.LispAfiAddress; | 19 | import org.onosproject.lisp.msg.types.LispAfiAddress; |
19 | 20 | ||
21 | +import java.util.List; | ||
22 | + | ||
20 | /** | 23 | /** |
21 | * LISP record section which is part of LISP map register message. | 24 | * LISP record section which is part of LISP map register message. |
22 | */ | 25 | */ |
... | @@ -72,6 +75,20 @@ public interface LispMapRecord { | ... | @@ -72,6 +75,20 @@ public interface LispMapRecord { |
72 | LispAfiAddress getEidPrefixAfi(); | 75 | LispAfiAddress getEidPrefixAfi(); |
73 | 76 | ||
74 | /** | 77 | /** |
78 | + * Obtains a collection of locator records. | ||
79 | + * | ||
80 | + * @return a collection of locator records | ||
81 | + */ | ||
82 | + List<LispLocatorRecord> getLocators(); | ||
83 | + | ||
84 | + /** | ||
85 | + * Writes LISP message object into communication channel. | ||
86 | + * | ||
87 | + * @param byteBuf byte buffer | ||
88 | + */ | ||
89 | + void writeTo(ByteBuf byteBuf); | ||
90 | + | ||
91 | + /** | ||
75 | * A builder of LISP map record. | 92 | * A builder of LISP map record. |
76 | */ | 93 | */ |
77 | interface MapRecordBuilder { | 94 | interface MapRecordBuilder { |
... | @@ -133,6 +150,14 @@ public interface LispMapRecord { | ... | @@ -133,6 +150,14 @@ public interface LispMapRecord { |
133 | MapRecordBuilder withEidPrefixAfi(LispAfiAddress prefix); | 150 | MapRecordBuilder withEidPrefixAfi(LispAfiAddress prefix); |
134 | 151 | ||
135 | /** | 152 | /** |
153 | + * Sets a collection of locator records. | ||
154 | + * | ||
155 | + * @param records a collection of locator records | ||
156 | + * @return MapRecordBuilder object | ||
157 | + */ | ||
158 | + MapRecordBuilder withLocators(List<LispLocatorRecord> records); | ||
159 | + | ||
160 | + /** | ||
136 | * Builds map record. | 161 | * Builds map record. |
137 | * | 162 | * |
138 | * @return map record instance | 163 | * @return map record instance | ... | ... |
... | @@ -159,12 +159,12 @@ public interface LispMapRegister extends LispMessage { | ... | @@ -159,12 +159,12 @@ public interface LispMapRegister extends LispMessage { |
159 | RegisterBuilder withAuthenticationData(byte[] authenticationData); | 159 | RegisterBuilder withAuthenticationData(byte[] authenticationData); |
160 | 160 | ||
161 | /** | 161 | /** |
162 | - * Adds a new record to record list. | 162 | + * Sets a collection of map records. |
163 | * | 163 | * |
164 | - * @param record record | 164 | + * @param mapRecords a collection of map records |
165 | * @return RegisterBuilder object | 165 | * @return RegisterBuilder object |
166 | */ | 166 | */ |
167 | - RegisterBuilder addRecord(LispMapRecord record); | 167 | + RegisterBuilder withMapRecords(List<LispMapRecord> mapRecords); |
168 | 168 | ||
169 | /** | 169 | /** |
170 | * Builds LISP map register message. | 170 | * Builds LISP map register message. | ... | ... |
... | @@ -210,20 +210,20 @@ public interface LispMapRequest extends LispMessage { | ... | @@ -210,20 +210,20 @@ public interface LispMapRequest extends LispMessage { |
210 | RequestBuilder withSourceEid(LispAfiAddress sourceEid); | 210 | RequestBuilder withSourceEid(LispAfiAddress sourceEid); |
211 | 211 | ||
212 | /** | 212 | /** |
213 | - * Adds ITR RLOC into RLOC collection. | 213 | + * Sets a collection of ITR RLOCs. |
214 | * | 214 | * |
215 | - * @param itrRloc ITR RLOC | 215 | + * @param itrRlocs a collection of ITR RLOCs |
216 | * @return RequestBuilder object | 216 | * @return RequestBuilder object |
217 | */ | 217 | */ |
218 | - RequestBuilder addItrRloc(LispAfiAddress itrRloc); | 218 | + RequestBuilder withItrRlocs(List<LispAfiAddress> itrRlocs); |
219 | 219 | ||
220 | /** | 220 | /** |
221 | - * Adds EID record into record collection. | 221 | + * Sets a collection of EID records. |
222 | * | 222 | * |
223 | - * @param record EID record | 223 | + * @param records a collection of EID records |
224 | * @return RequestBuilder object | 224 | * @return RequestBuilder object |
225 | */ | 225 | */ |
226 | - RequestBuilder addEidRecord(LispEidRecord record); | 226 | + RequestBuilder withEidRecords(List<LispEidRecord> records); |
227 | 227 | ||
228 | /** | 228 | /** |
229 | * Builds LISP map request message. | 229 | * Builds LISP map request message. | ... | ... |
1 | +/* | ||
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 | + */ | ||
16 | +package org.onosproject.lisp.msg.protocols; | ||
17 | + | ||
18 | +import com.google.common.testing.EqualsTester; | ||
19 | +import org.junit.Before; | ||
20 | +import org.junit.Test; | ||
21 | + | ||
22 | +import static org.hamcrest.MatcherAssert.assertThat; | ||
23 | +import static org.hamcrest.Matchers.is; | ||
24 | + | ||
25 | +/** | ||
26 | + * Unit tests for DefaultLispLocatorRecord class. | ||
27 | + */ | ||
28 | +public final class DefaultLispLocatorRecordTest { | ||
29 | + | ||
30 | + private LispLocatorRecord record1; | ||
31 | + private LispLocatorRecord sameAsRecord1; | ||
32 | + private LispLocatorRecord record2; | ||
33 | + | ||
34 | + @Before | ||
35 | + public void setup() { | ||
36 | + | ||
37 | + LispLocatorRecord.LocatorRecordBuilder builder1 = | ||
38 | + new DefaultLispLocatorRecord.DefaultLocatorRecordBuilder(); | ||
39 | + | ||
40 | + record1 = builder1 | ||
41 | + .withPriority((byte) 0x01) | ||
42 | + .withWeight((byte) 0x01) | ||
43 | + .withMulticastPriority((byte) 0x01) | ||
44 | + .withMulticastWeight((byte) 0x01) | ||
45 | + .withLocalLocator(true) | ||
46 | + .withRlocProbed(false) | ||
47 | + .withRouted(true) | ||
48 | + .build(); | ||
49 | + | ||
50 | + LispLocatorRecord.LocatorRecordBuilder builder2 = | ||
51 | + new DefaultLispLocatorRecord.DefaultLocatorRecordBuilder(); | ||
52 | + | ||
53 | + sameAsRecord1 = builder2 | ||
54 | + .withPriority((byte) 0x01) | ||
55 | + .withWeight((byte) 0x01) | ||
56 | + .withMulticastPriority((byte) 0x01) | ||
57 | + .withMulticastWeight((byte) 0x01) | ||
58 | + .withLocalLocator(true) | ||
59 | + .withRlocProbed(false) | ||
60 | + .withRouted(true) | ||
61 | + .build(); | ||
62 | + | ||
63 | + LispLocatorRecord.LocatorRecordBuilder builder3 = | ||
64 | + new DefaultLispLocatorRecord.DefaultLocatorRecordBuilder(); | ||
65 | + | ||
66 | + record2 = builder3 | ||
67 | + .withPriority((byte) 0x02) | ||
68 | + .withWeight((byte) 0x02) | ||
69 | + .withMulticastPriority((byte) 0x02) | ||
70 | + .withMulticastWeight((byte) 0x02) | ||
71 | + .withLocalLocator(false) | ||
72 | + .withRlocProbed(true) | ||
73 | + .withRouted(false) | ||
74 | + .build(); | ||
75 | + } | ||
76 | + | ||
77 | + @Test | ||
78 | + public void testEquality() { | ||
79 | + new EqualsTester() | ||
80 | + .addEqualityGroup(record1, sameAsRecord1) | ||
81 | + .addEqualityGroup(record2).testEquals(); | ||
82 | + } | ||
83 | + | ||
84 | + @Test | ||
85 | + public void testConstruction() { | ||
86 | + DefaultLispLocatorRecord record = (DefaultLispLocatorRecord) record1; | ||
87 | + | ||
88 | + assertThat(record.getPriority(), is((byte) 0x01)); | ||
89 | + assertThat(record.getWeight(), is((byte) 0x01)); | ||
90 | + assertThat(record.getMulticastPriority(), is((byte) 0x01)); | ||
91 | + assertThat(record.getMulticastWeight(), is((byte) 0x01)); | ||
92 | + assertThat(record.isLocalLocator(), is(true)); | ||
93 | + assertThat(record.isRlocProbed(), is(false)); | ||
94 | + assertThat(record.isRouted(), is(true)); | ||
95 | + } | ||
96 | +} |
... | @@ -25,7 +25,7 @@ import static org.hamcrest.Matchers.is; | ... | @@ -25,7 +25,7 @@ import static org.hamcrest.Matchers.is; |
25 | /** | 25 | /** |
26 | * Unit tests for DefaultLispMapNotify class. | 26 | * Unit tests for DefaultLispMapNotify class. |
27 | */ | 27 | */ |
28 | -public class DefaultLispMapNotifyTest { | 28 | +public final class DefaultLispMapNotifyTest { |
29 | 29 | ||
30 | private LispMapNotify notify1; | 30 | private LispMapNotify notify1; |
31 | private LispMapNotify sameAsNotify1; | 31 | private LispMapNotify sameAsNotify1; | ... | ... |
... | @@ -25,7 +25,7 @@ import static org.hamcrest.Matchers.is; | ... | @@ -25,7 +25,7 @@ import static org.hamcrest.Matchers.is; |
25 | /** | 25 | /** |
26 | * Unit tests for DefaultLispMapRecord class. | 26 | * Unit tests for DefaultLispMapRecord class. |
27 | */ | 27 | */ |
28 | -public class DefaultLispMapRecordTest { | 28 | +public final class DefaultLispMapRecordTest { |
29 | 29 | ||
30 | private LispMapRecord record1; | 30 | private LispMapRecord record1; |
31 | private LispMapRecord sameAsRecord1; | 31 | private LispMapRecord sameAsRecord1; | ... | ... |
... | @@ -25,7 +25,7 @@ import static org.hamcrest.Matchers.is; | ... | @@ -25,7 +25,7 @@ import static org.hamcrest.Matchers.is; |
25 | /** | 25 | /** |
26 | * Unit tests for DefaultLispMapRegister class. | 26 | * Unit tests for DefaultLispMapRegister class. |
27 | */ | 27 | */ |
28 | -public class DefaultLispMapRegisterTest { | 28 | +public final class DefaultLispMapRegisterTest { |
29 | 29 | ||
30 | private LispMapRegister register1; | 30 | private LispMapRegister register1; |
31 | private LispMapRegister sameAsRegister1; | 31 | private LispMapRegister sameAsRegister1; | ... | ... |
... | @@ -25,7 +25,7 @@ import static org.hamcrest.Matchers.is; | ... | @@ -25,7 +25,7 @@ import static org.hamcrest.Matchers.is; |
25 | /** | 25 | /** |
26 | * Unit tests for DefaultLispMapReply class. | 26 | * Unit tests for DefaultLispMapReply class. |
27 | */ | 27 | */ |
28 | -public class DefaultLispMapReplyTest { | 28 | +public final class DefaultLispMapReplyTest { |
29 | 29 | ||
30 | private LispMapReply reply1; | 30 | private LispMapReply reply1; |
31 | private LispMapReply sameAsReply1; | 31 | private LispMapReply sameAsReply1; | ... | ... |
... | @@ -25,7 +25,7 @@ import static org.hamcrest.Matchers.is; | ... | @@ -25,7 +25,7 @@ import static org.hamcrest.Matchers.is; |
25 | /** | 25 | /** |
26 | * Unit tests for DefaultLispMapRequest class. | 26 | * Unit tests for DefaultLispMapRequest class. |
27 | */ | 27 | */ |
28 | -public class DefaultLispMapRequestTest { | 28 | +public final class DefaultLispMapRequestTest { |
29 | 29 | ||
30 | private LispMapRequest request1; | 30 | private LispMapRequest request1; |
31 | private LispMapRequest sameAsRequest1; | 31 | private LispMapRequest sameAsRequest1; | ... | ... |
1 | +/* | ||
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 | + */ | ||
16 | +package org.onlab.util; | ||
17 | + | ||
18 | +/** | ||
19 | + * Provide a set of byte operations. | ||
20 | + */ | ||
21 | +public final class ByteOperator { | ||
22 | + | ||
23 | + /** | ||
24 | + * Private constructor which prevents from external instantiation. | ||
25 | + */ | ||
26 | + private ByteOperator() { | ||
27 | + | ||
28 | + } | ||
29 | + | ||
30 | + /** | ||
31 | + * Obtains a specific bit value from a byte with given index number. | ||
32 | + * | ||
33 | + * @param value byte value | ||
34 | + * @param index index number | ||
35 | + * @return a specific bit value from a byte | ||
36 | + */ | ||
37 | + public static boolean getBit(byte value, int index) { | ||
38 | + // the length of byte should always be positive whiles less than 8 | ||
39 | + if (index > 7 || index < 0) { | ||
40 | + return false; | ||
41 | + } | ||
42 | + | ||
43 | + int bitMask = getHex((int) Math.pow(2, index)); | ||
44 | + return (value & bitMask) == bitMask; | ||
45 | + } | ||
46 | + | ||
47 | + /** | ||
48 | + * Converts boolean value into bit. | ||
49 | + * | ||
50 | + * @param value boolean value | ||
51 | + * @param bit bit value | ||
52 | + * @return converted bit value | ||
53 | + */ | ||
54 | + public static byte toBit(boolean value, int bit) { | ||
55 | + return (byte) (value ? bit : 0x00); | ||
56 | + } | ||
57 | + | ||
58 | + /** | ||
59 | + * Convert decimal integer into hex integer. | ||
60 | + * | ||
61 | + * @param decimal decimal formatted integer | ||
62 | + * @return hex formatted integer | ||
63 | + */ | ||
64 | + private static int getHex(int decimal) { | ||
65 | + return Integer.valueOf(String.valueOf(decimal), 16); | ||
66 | + } | ||
67 | +} |
1 | +/* | ||
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 | + */ | ||
16 | +package org.onlab.util; | ||
17 | + | ||
18 | +import org.junit.Test; | ||
19 | + | ||
20 | +import static org.hamcrest.Matchers.is; | ||
21 | +import static org.junit.Assert.assertThat; | ||
22 | + | ||
23 | +/** | ||
24 | + * Unit tests for ByteOperator. | ||
25 | + */ | ||
26 | +public class ByteOperatorTest { | ||
27 | + | ||
28 | + @Test | ||
29 | + public void testGetBit() { | ||
30 | + byte eight = 0x08; | ||
31 | + assertThat(ByteOperator.getBit(eight, 0), is(false)); | ||
32 | + assertThat(ByteOperator.getBit(eight, 1), is(false)); | ||
33 | + assertThat(ByteOperator.getBit(eight, 2), is(false)); | ||
34 | + assertThat(ByteOperator.getBit(eight, 3), is(true)); | ||
35 | + assertThat(ByteOperator.getBit(eight, 4), is(false)); | ||
36 | + assertThat(ByteOperator.getBit(eight, 5), is(false)); | ||
37 | + assertThat(ByteOperator.getBit(eight, 6), is(false)); | ||
38 | + assertThat(ByteOperator.getBit(eight, 7), is(false)); | ||
39 | + | ||
40 | + byte one = 0x01; | ||
41 | + assertThat(ByteOperator.getBit(one, 0), is(true)); | ||
42 | + assertThat(ByteOperator.getBit(one, 1), is(false)); | ||
43 | + assertThat(ByteOperator.getBit(one, 2), is(false)); | ||
44 | + assertThat(ByteOperator.getBit(one, 3), is(false)); | ||
45 | + assertThat(ByteOperator.getBit(one, 4), is(false)); | ||
46 | + assertThat(ByteOperator.getBit(one, 5), is(false)); | ||
47 | + assertThat(ByteOperator.getBit(one, 6), is(false)); | ||
48 | + assertThat(ByteOperator.getBit(one, 7), is(false)); | ||
49 | + } | ||
50 | +} |
-
Please register or login to post a comment