blob: b412cdb0d6fdb129a487e6d646b39add645ca248 [file] [log] [blame]
Jian Li451175e2016-07-19 23:22:20 +09001/*
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.protocols;
17
Jian Li20850d32016-08-04 02:15:57 +090018import com.google.common.base.Objects;
Jian Lia7b394d2016-08-21 23:11:46 +090019import com.google.common.collect.ImmutableList;
20import com.google.common.collect.Lists;
Jian Li451175e2016-07-19 23:22:20 +090021import io.netty.buffer.ByteBuf;
Jian Li47671902016-08-11 01:18:18 +090022import org.onlab.util.ByteOperator;
Jian Li26069e22016-08-10 22:00:52 +090023import org.onosproject.lisp.msg.exceptions.LispParseError;
Jian Lia7b394d2016-08-21 23:11:46 +090024import org.onosproject.lisp.msg.exceptions.LispReaderException;
Jian Liedc5db12016-08-23 17:30:19 +090025import org.onosproject.lisp.msg.exceptions.LispWriterException;
Jian Lia7b394d2016-08-21 23:11:46 +090026
27import java.util.List;
Jian Li451175e2016-07-19 23:22:20 +090028
Jian Li20850d32016-08-04 02:15:57 +090029import static com.google.common.base.MoreObjects.toStringHelper;
Jian Liedc5db12016-08-23 17:30:19 +090030import static org.onosproject.lisp.msg.protocols.DefaultLispMapRecord.MapRecordWriter;
Jian Li20850d32016-08-04 02:15:57 +090031
Jian Li451175e2016-07-19 23:22:20 +090032/**
33 * Default LISP map reply message class.
34 */
Jian Lif59c0ad2016-08-02 18:11:30 +090035public final class DefaultLispMapReply implements LispMapReply {
36
37 private final long nonce;
Jian Lif59c0ad2016-08-02 18:11:30 +090038 private final boolean probe;
39 private final boolean etr;
40 private final boolean security;
Jian Lia7b394d2016-08-21 23:11:46 +090041 private final List<LispMapRecord> mapRecords;
Jian Lif59c0ad2016-08-02 18:11:30 +090042
43 /**
44 * A private constructor that protects object instantiation from external.
45 *
46 * @param nonce nonce
Jian Lif59c0ad2016-08-02 18:11:30 +090047 * @param probe probe flag
48 * @param etr etr flag
49 * @param security security flag
50 */
Jian Li42b3e432016-08-31 01:05:20 +090051 private DefaultLispMapReply(long nonce, boolean probe, boolean etr,
52 boolean security, List<LispMapRecord> mapRecords) {
Jian Lif59c0ad2016-08-02 18:11:30 +090053 this.nonce = nonce;
Jian Lif59c0ad2016-08-02 18:11:30 +090054 this.probe = probe;
55 this.etr = etr;
56 this.security = security;
Jian Lia7b394d2016-08-21 23:11:46 +090057 this.mapRecords = mapRecords;
Jian Lif59c0ad2016-08-02 18:11:30 +090058 }
59
Jian Li451175e2016-07-19 23:22:20 +090060 @Override
61 public LispType getType() {
Jian Lif59c0ad2016-08-02 18:11:30 +090062 return LispType.LISP_MAP_REPLY;
Jian Li451175e2016-07-19 23:22:20 +090063 }
64
65 @Override
66 public void writeTo(ByteBuf byteBuf) {
Jian Lif59c0ad2016-08-02 18:11:30 +090067 // TODO: serialize LispMapReply message
Jian Li451175e2016-07-19 23:22:20 +090068 }
69
70 @Override
71 public Builder createBuilder() {
Jian Li525fded2016-08-04 01:15:33 +090072 return new DefaultReplyBuilder();
Jian Li451175e2016-07-19 23:22:20 +090073 }
Jian Li719b3bf2016-07-22 00:38:29 +090074
75 @Override
76 public boolean isProbe() {
Jian Liedc5db12016-08-23 17:30:19 +090077 return probe;
Jian Li719b3bf2016-07-22 00:38:29 +090078 }
79
80 @Override
81 public boolean isEtr() {
Jian Liedc5db12016-08-23 17:30:19 +090082 return etr;
Jian Li719b3bf2016-07-22 00:38:29 +090083 }
84
85 @Override
86 public boolean isSecurity() {
Jian Liedc5db12016-08-23 17:30:19 +090087 return security;
Jian Li719b3bf2016-07-22 00:38:29 +090088 }
89
90 @Override
Jian Li42b3e432016-08-31 01:05:20 +090091 public int getRecordCount() {
92 return mapRecords.size();
Jian Li719b3bf2016-07-22 00:38:29 +090093 }
94
95 @Override
96 public long getNonce() {
Jian Liedc5db12016-08-23 17:30:19 +090097 return nonce;
Jian Li719b3bf2016-07-22 00:38:29 +090098 }
99
Jian Li20850d32016-08-04 02:15:57 +0900100 @Override
Jian Lia7b394d2016-08-21 23:11:46 +0900101 public List<LispMapRecord> getMapRecords() {
102 return ImmutableList.copyOf(mapRecords);
103 }
104
105 @Override
Jian Li20850d32016-08-04 02:15:57 +0900106 public String toString() {
107 return toStringHelper(this)
108 .add("type", getType())
109 .add("nonce", nonce)
Jian Li20850d32016-08-04 02:15:57 +0900110 .add("probe", probe)
111 .add("etr", etr)
Jian Lia7b394d2016-08-21 23:11:46 +0900112 .add("security", security)
113 .add("map records", mapRecords).toString();
Jian Li20850d32016-08-04 02:15:57 +0900114 }
115
116 @Override
117 public boolean equals(Object o) {
118 if (this == o) {
119 return true;
120 }
121 if (o == null || getClass() != o.getClass()) {
122 return false;
123 }
124 DefaultLispMapReply that = (DefaultLispMapReply) o;
125 return Objects.equal(nonce, that.nonce) &&
Jian Li20850d32016-08-04 02:15:57 +0900126 Objects.equal(probe, that.probe) &&
127 Objects.equal(etr, that.etr) &&
Jian Lia7b394d2016-08-21 23:11:46 +0900128 Objects.equal(security, that.security) &&
129 Objects.equal(mapRecords, that.mapRecords);
Jian Li20850d32016-08-04 02:15:57 +0900130 }
131
132 @Override
133 public int hashCode() {
Jian Li42b3e432016-08-31 01:05:20 +0900134 return Objects.hashCode(nonce, probe, etr, security, mapRecords);
Jian Li20850d32016-08-04 02:15:57 +0900135 }
136
Jian Li719b3bf2016-07-22 00:38:29 +0900137 public static final class DefaultReplyBuilder implements ReplyBuilder {
138
Jian Lif59c0ad2016-08-02 18:11:30 +0900139 private long nonce;
Jian Lif59c0ad2016-08-02 18:11:30 +0900140 private boolean probe;
141 private boolean etr;
142 private boolean security;
Jian Lid4e63702016-08-30 18:29:20 +0900143 private List<LispMapRecord> mapRecords = Lists.newArrayList();
Jian Li719b3bf2016-07-22 00:38:29 +0900144
145 @Override
146 public LispType getType() {
Jian Lif59c0ad2016-08-02 18:11:30 +0900147 return LispType.LISP_MAP_REPLY;
Jian Li719b3bf2016-07-22 00:38:29 +0900148 }
149
150 @Override
Jian Lif59c0ad2016-08-02 18:11:30 +0900151 public ReplyBuilder withIsProbe(boolean probe) {
152 this.probe = probe;
153 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900154 }
155
156 @Override
Jian Lif59c0ad2016-08-02 18:11:30 +0900157 public ReplyBuilder withIsEtr(boolean etr) {
158 this.etr = etr;
159 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900160 }
161
162 @Override
Jian Lif59c0ad2016-08-02 18:11:30 +0900163 public ReplyBuilder withIsSecurity(boolean security) {
164 this.security = security;
165 return this;
Jian Li719b3bf2016-07-22 00:38:29 +0900166 }
167
168 @Override
Jian Li719b3bf2016-07-22 00:38:29 +0900169 public ReplyBuilder withNonce(long nonce) {
Jian Lif59c0ad2016-08-02 18:11:30 +0900170 this.nonce = nonce;
171 return this;
172 }
173
174 @Override
Jian Lia7b394d2016-08-21 23:11:46 +0900175 public ReplyBuilder withMapRecords(List<LispMapRecord> mapRecords) {
Jian Lie4ba2a42016-08-29 20:24:15 +0900176 if (this.mapRecords != null) {
177 this.mapRecords = ImmutableList.copyOf(mapRecords);
Jian Lie4ba2a42016-08-29 20:24:15 +0900178 }
Jian Lia7b394d2016-08-21 23:11:46 +0900179 return this;
180 }
181
182 @Override
Jian Li525fded2016-08-04 01:15:33 +0900183 public LispMapReply build() {
Jian Li42b3e432016-08-31 01:05:20 +0900184 return new DefaultLispMapReply(nonce, probe, etr, security, mapRecords);
Jian Li719b3bf2016-07-22 00:38:29 +0900185 }
186 }
Jian Li26069e22016-08-10 22:00:52 +0900187
188 /**
Jian Liedc5db12016-08-23 17:30:19 +0900189 * A LISP message reader for MapReply message.
Jian Li26069e22016-08-10 22:00:52 +0900190 */
Jian Liedc5db12016-08-23 17:30:19 +0900191 public static final class ReplyReader implements LispMessageReader<LispMapReply> {
Jian Li26069e22016-08-10 22:00:52 +0900192
Jian Li47671902016-08-11 01:18:18 +0900193 private static final int PROBE_INDEX = 3;
194 private static final int ETR_INDEX = 2;
195 private static final int SECURITY_INDEX = 1;
196 private static final int RESERVED_SKIP_LENGTH = 2;
197
Jian Li26069e22016-08-10 22:00:52 +0900198 @Override
Jian Lia7b394d2016-08-21 23:11:46 +0900199 public LispMapReply readFrom(ByteBuf byteBuf) throws LispParseError, LispReaderException {
Jian Li47671902016-08-11 01:18:18 +0900200
201 if (byteBuf.readerIndex() != 0) {
202 return null;
203 }
204
205 byte typeWithFlags = byteBuf.readByte();
206
207 // probe -> 1 bit
208 boolean probe = ByteOperator.getBit(typeWithFlags, PROBE_INDEX);
209
210 // etr -> 1bit
211 boolean etr = ByteOperator.getBit(typeWithFlags, ETR_INDEX);
212
213 // security -> 1 bit
214 boolean security = ByteOperator.getBit(typeWithFlags, SECURITY_INDEX);
215
216 // skip two bytes as they represent reserved fields
217 byteBuf.skipBytes(RESERVED_SKIP_LENGTH);
218
219 // record count -> 8 bits
220 byte recordCount = (byte) byteBuf.readUnsignedByte();
221
222 // nonce -> 64 bits
223 long nonce = byteBuf.readLong();
224
Jian Lia7b394d2016-08-21 23:11:46 +0900225 List<LispMapRecord> mapRecords = Lists.newArrayList();
226 for (int i = 0; i < recordCount; i++) {
227 mapRecords.add(new DefaultLispMapRecord.MapRecordReader().readFrom(byteBuf));
228 }
Jian Li47671902016-08-11 01:18:18 +0900229
230 return new DefaultReplyBuilder()
231 .withIsProbe(probe)
232 .withIsEtr(etr)
233 .withIsSecurity(security)
Jian Li47671902016-08-11 01:18:18 +0900234 .withNonce(nonce)
Jian Lib26d3502016-08-31 01:43:24 +0900235 .withMapRecords(mapRecords)
Jian Li47671902016-08-11 01:18:18 +0900236 .build();
Jian Li26069e22016-08-10 22:00:52 +0900237 }
238 }
Jian Liedc5db12016-08-23 17:30:19 +0900239
240 /**
241 * A LISP message writer for MapReply message.
242 */
243 public static final class ReplyWriter implements LispMessageWriter<LispMapReply> {
244
245 private static final int REPLY_MSG_TYPE = 2;
246 private static final int REPLY_SHIFT_BIT = 4;
247
248 private static final int PROBE_FLAG_SHIFT_BIT = 3;
249 private static final int ETR_FLAG_SHIFT_BIT = 2;
250 private static final int SECURITY_FLAG_SHIFT_BIT = 1;
251
252 private static final int ENABLE_BIT = 1;
253 private static final int DISABLE_BIT = 0;
254
255 private static final int UNUSED_ZERO = 0;
256
257 @Override
258 public void writeTo(ByteBuf byteBuf, LispMapReply message) throws LispWriterException {
259
260 // specify LISP message type
261 byte msgType = (byte) (REPLY_MSG_TYPE << REPLY_SHIFT_BIT);
262
263 // probe flag
264 byte probe = DISABLE_BIT;
265 if (message.isProbe()) {
266 probe = (byte) (ENABLE_BIT << PROBE_FLAG_SHIFT_BIT);
267 }
268
269 // etr flag
270 byte etr = DISABLE_BIT;
271 if (message.isEtr()) {
272 etr = (byte) (ENABLE_BIT << ETR_FLAG_SHIFT_BIT);
273 }
274
275 // security flag
276 byte security = DISABLE_BIT;
277 if (message.isSecurity()) {
278 security = (byte) (ENABLE_BIT << SECURITY_FLAG_SHIFT_BIT);
279 }
280
281 byteBuf.writeByte((byte) (msgType + probe + etr + security));
282
283 // reserved field
284 byteBuf.writeShort((short) UNUSED_ZERO);
285
286 // record count
Jian Li42b3e432016-08-31 01:05:20 +0900287 byteBuf.writeByte(message.getMapRecords().size());
Jian Liedc5db12016-08-23 17:30:19 +0900288
289 // nonce
290 byteBuf.writeLong(message.getNonce());
291
292 // serialize map records
293 MapRecordWriter writer = new MapRecordWriter();
294 List<LispMapRecord> records = message.getMapRecords();
295
296 for (int i = 0; i < records.size(); i++) {
297 writer.writeTo(byteBuf, records.get(i));
298 }
299 }
300 }
Jian Li451175e2016-07-19 23:22:20 +0900301}