blob: 4d14a72c38695e029cf2fc31e93b984886149aad [file] [log] [blame]
Jian Li672ebda2017-02-06 20:21:04 +09001/*
2 * Copyright 2017-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 Lif4bfbaa2017-02-08 14:59:58 +090018import com.google.common.collect.ImmutableList;
19import com.google.common.collect.Lists;
20import io.netty.buffer.ByteBuf;
21import org.onlab.packet.DeserializationException;
22import org.onosproject.lisp.msg.exceptions.LispParseError;
23import org.onosproject.lisp.msg.exceptions.LispReaderException;
24import org.onosproject.lisp.msg.exceptions.LispWriterException;
25import org.onosproject.lisp.msg.protocols.DefaultLispReferralRecord.ReferralRecordReader;
26import org.onosproject.lisp.msg.protocols.DefaultLispReferralRecord.ReferralRecordWriter;
27import org.slf4j.Logger;
28import org.slf4j.LoggerFactory;
29
30import java.util.List;
31import java.util.Objects;
32
33import static com.google.common.base.MoreObjects.toStringHelper;
34import static org.onosproject.lisp.msg.protocols.LispType.LISP_MAP_REFERRAL;
35
Jian Li672ebda2017-02-06 20:21:04 +090036/**
37 * Default LISP referral message class.
38 */
Jian Lif4bfbaa2017-02-08 14:59:58 +090039public final class DefaultLispMapReferral extends AbstractLispMessage
40 implements LispMapReferral {
41
42 private static final Logger log =
43 LoggerFactory.getLogger(DefaultLispMapReferral.class);
44
45 private final long nonce;
46 private final List<LispReferralRecord> referralRecords;
47
48 static final MapReferralWriter WRITER;
49
50 static {
51 WRITER = new MapReferralWriter();
52 }
53
54 /**
55 * A private constructor that protects object instantiation from external.
56 *
57 * @param nonce nonce
58 * @param referralRecords a collection of referral records
59 */
60 private DefaultLispMapReferral(long nonce,
61 List<LispReferralRecord> referralRecords) {
62 this.nonce = nonce;
63 this.referralRecords = referralRecords;
64 }
65
66 @Override
67 public LispType getType() {
68 return LISP_MAP_REFERRAL;
69 }
70
71 @Override
72 public void writeTo(ByteBuf byteBuf) throws LispWriterException {
73 WRITER.writeTo(byteBuf, this);
74 }
75
76 @Override
77 public Builder createBuilder() {
78 return new DefaultMapReferralBuilder();
79 }
80
81 @Override
82 public int getRecordCount() {
83 return referralRecords.size();
84 }
85
86 @Override
87 public long getNonce() {
88 return nonce;
89 }
90
91 @Override
92 public List<LispReferralRecord> getReferralRecords() {
93 return ImmutableList.copyOf(referralRecords);
94 }
95
96 @Override
97 public String toString() {
98 return toStringHelper(this)
99 .add("type", getType())
100 .add("nonce", nonce)
101 .add("referralRecords", referralRecords)
102 .toString();
103 }
104
105 @Override
106 public boolean equals(Object o) {
107 if (this == o) {
108 return true;
109 }
110 if (o == null || getClass() != o.getClass()) {
111 return false;
112 }
113
114 DefaultLispMapReferral that = (DefaultLispMapReferral) o;
115 return Objects.equals(nonce, that.nonce);
116 }
117
118 @Override
119 public int hashCode() {
120 return Objects.hashCode(nonce);
121 }
122
123 public static final class DefaultMapReferralBuilder
124 implements MapReferralBuilder {
125
126 private long nonce;
127 private List<LispReferralRecord> referralRecords = Lists.newArrayList();
128
129 @Override
130 public LispType getType() {
131 return LISP_MAP_REFERRAL;
132 }
133
134 @Override
135 public MapReferralBuilder withNonce(long nonce) {
136 this.nonce = nonce;
137 return this;
138 }
139
140 @Override
141 public MapReferralBuilder withReferralRecords(List<LispReferralRecord> records) {
142 if (referralRecords != null) {
143 this.referralRecords = ImmutableList.copyOf(records);
144 }
145 return this;
146 }
147
148 @Override
149 public LispMapReferral build() {
150 return new DefaultLispMapReferral(nonce, referralRecords);
151 }
152 }
153
154 /**
155 * A LISP message reader for MapReferral message.
156 */
157 public static final class MapReferralReader
158 implements LispMessageReader<LispMapReferral> {
159
160 private static final int RESERVED_SKIP_LENGTH = 3;
161
162 @Override
163 public LispMapReferral readFrom(ByteBuf byteBuf) throws LispParseError,
164 LispReaderException, DeserializationException {
165
166 if (byteBuf.readerIndex() != 0) {
167 return null;
168 }
169
170 // let's skip the reserved field
171 byteBuf.skipBytes(RESERVED_SKIP_LENGTH);
172
173 // record count -> 8 bits
174 byte recordCount = (byte) byteBuf.readUnsignedByte();
175
176 // nonce -> 64 bits
177 long nonce = byteBuf.readLong();
178
179 List<LispReferralRecord> referralRecords = Lists.newArrayList();
180 for (int i = 0; i < recordCount; i++) {
181 referralRecords.add(new ReferralRecordReader().readFrom(byteBuf));
182 }
183
184 return new DefaultMapReferralBuilder()
185 .withNonce(nonce)
186 .withReferralRecords(referralRecords)
187 .build();
188 }
189 }
190
191 /**
192 * A LISP message writer for MapReferral message.
193 */
194 public static final class MapReferralWriter
195 implements LispMessageWriter<LispMapReferral> {
196
197 private static final int REFERRAL_SHIFT_BIT = 4;
198
199 private static final int UNUSED_ZERO = 0;
200
201 @Override
202 public void writeTo(ByteBuf byteBuf, LispMapReferral message)
203 throws LispWriterException {
204
205 // specify LISP message type
206 byte msgType =
207 (byte) (LISP_MAP_REFERRAL.getTypeCode() << REFERRAL_SHIFT_BIT);
208
209 // fill zero into reserved field
210 byteBuf.writeShort(UNUSED_ZERO);
211 byteBuf.writeByte(UNUSED_ZERO);
212
213 // record count
214 byteBuf.writeByte(message.getReferralRecords().size());
215
216 // nonce
217 byteBuf.writeLong(message.getNonce());
218
219 // serialize referral records
220 ReferralRecordWriter writer = new ReferralRecordWriter();
221 List<LispReferralRecord> records = message.getReferralRecords();
222
Jian Li3282a342017-05-23 14:30:15 +0900223 for (LispReferralRecord record : records) {
224 writer.writeTo(byteBuf, record);
Jian Lif4bfbaa2017-02-08 14:59:58 +0900225 }
226 }
227 }
Jian Li672ebda2017-02-06 20:21:04 +0900228}