blob: 7ce4e7a162435c303deba96e0487c208f6118adb [file] [log] [blame]
Jian Li52015762016-10-04 17:51:16 +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.types;
17
18import com.google.common.collect.ImmutableList;
19import com.google.common.collect.Lists;
20import io.netty.buffer.ByteBuf;
21import org.onosproject.lisp.msg.exceptions.LispParseError;
22import org.onosproject.lisp.msg.exceptions.LispReaderException;
23import org.onosproject.lisp.msg.exceptions.LispWriterException;
24
25import java.util.List;
26import java.util.Objects;
27
28import static com.google.common.base.MoreObjects.toStringHelper;
29
30/**
31 * Network Address Translation (NAT) address class.
32 * <p>
Jian Li89c9ca92016-11-11 04:09:02 +090033 * Instance ID type is defined in draft-ietf-lisp-lcaf-20
34 * https://tools.ietf.org/html/draft-ietf-lisp-lcaf-20#page-12
35 *
Jian Li52015762016-10-04 17:51:16 +090036 * <pre>
37 * {@literal
Jian Li3109de82016-12-06 01:34:08 +090038 * 0 1 2 3
39 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
Jian Li52015762016-10-04 17:51:16 +090040 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
41 * | AFI = 16387 | Rsvd1 | Flags |
42 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Jian Li89c9ca92016-11-11 04:09:02 +090043 * | Type = 7 | Rsvd2 | Length |
Jian Li52015762016-10-04 17:51:16 +090044 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
45 * | MS UDP Port Number | ETR UDP Port Number |
46 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
47 * | AFI = x | Global ETR RLOC Address ... |
48 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
49 * | AFI = x | MS RLOC Address ... |
50 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
51 * | AFI = x | Private ETR RLOC Address ... |
52 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
53 * | AFI = x | RTR RLOC Address 1 ... |
54 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
55 * | AFI = x | RTR RLOC Address k ... |
56 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
57 * }</pre>
58 */
59public final class LispNatLcafAddress extends LispLcafAddress {
60
61 private final short msUdpPortNumber;
62 private final short etrUdpPortNumber;
63 private final LispAfiAddress globalEtrRlocAddress;
64 private final LispAfiAddress msRlocAddress;
65 private final LispAfiAddress privateEtrRlocAddress;
66 private final List<LispAfiAddress> rtrRlocAddresses;
67
68 /**
69 * Initializes NAT type LCAF address.
70 *
71 * @param reserved2 reserved2
72 * @param length length
73 * @param msUdpPortNumber Map Server (MS) UDP port number
74 * @param etrUdpPortNumber ETR UDP port number
75 * @param globalEtrRlocAddress global ETR RLOC address
76 * @param msRlocAddress Map Server (MS) RLOC address
77 * @param privateEtrRlocAddress private ETR RLOC address
78 * @param rtrRlocAddresses a collection of RTR RLOC addresses
79 */
80 private LispNatLcafAddress(byte reserved2, short length, short msUdpPortNumber,
81 short etrUdpPortNumber, LispAfiAddress globalEtrRlocAddress,
82 LispAfiAddress msRlocAddress, LispAfiAddress privateEtrRlocAddress,
83 List<LispAfiAddress> rtrRlocAddresses) {
84 super(LispCanonicalAddressFormatEnum.NAT, reserved2, length);
85 this.msUdpPortNumber = msUdpPortNumber;
86 this.etrUdpPortNumber = etrUdpPortNumber;
87 this.globalEtrRlocAddress = globalEtrRlocAddress;
88 this.msRlocAddress = msRlocAddress;
89 this.privateEtrRlocAddress = privateEtrRlocAddress;
90 this.rtrRlocAddresses = ImmutableList.copyOf(rtrRlocAddresses);
91 }
92
93 /**
94 * Obtains Map Server UDP port number.
95 *
96 * @return Map Server UDP port number
97 */
98 public short getMsUdpPortNumber() {
99 return msUdpPortNumber;
100 }
101
102 /**
103 * Obtains ETR UDP port number.
104 *
105 * @return ETR UDP port number
106 */
107 public short getEtrUdpPortNumber() {
108 return etrUdpPortNumber;
109 }
110
111 /**
112 * Obtains global ETR RLOC address.
113 *
114 * @return global ETR
115 */
116 public LispAfiAddress getGlobalEtrRlocAddress() {
117 return globalEtrRlocAddress;
118 }
119
120 /**
121 * Obtains Map Server RLOC address.
122 *
123 * @return Map Server RLOC address
124 */
125 public LispAfiAddress getMsRlocAddress() {
126 return msRlocAddress;
127 }
128
129 /**
130 * Obtains private ETR RLOC address.
131 *
132 * @return private ETR RLOC address
133 */
134 public LispAfiAddress getPrivateEtrRlocAddress() {
135 return privateEtrRlocAddress;
136 }
137
138 /**
139 * Obtains a collection of RTR RLOC addresses.
140 *
141 * @return a collection of RTR RLOC addresses
142 */
143 public List<LispAfiAddress> getRtrRlocAddresses() {
144 return ImmutableList.copyOf(rtrRlocAddresses);
145 }
146
147 @Override
148 public int hashCode() {
149 return Objects.hash(msUdpPortNumber, etrUdpPortNumber,
150 globalEtrRlocAddress, msRlocAddress, privateEtrRlocAddress);
151 }
152
153 @Override
154 public boolean equals(Object obj) {
155 if (this == obj) {
156 return true;
157 }
158
159 if (obj instanceof LispNatLcafAddress) {
160 final LispNatLcafAddress other = (LispNatLcafAddress) obj;
161 return Objects.equals(this.msUdpPortNumber, other.msUdpPortNumber) &&
162 Objects.equals(this.etrUdpPortNumber, other.etrUdpPortNumber) &&
163 Objects.equals(this.globalEtrRlocAddress, other.globalEtrRlocAddress) &&
164 Objects.equals(this.msRlocAddress, other.msRlocAddress) &&
yoonseon980cd7c2016-11-18 14:18:46 -0800165 Objects.equals(this.privateEtrRlocAddress, other.privateEtrRlocAddress) &&
166 Objects.equals(this.rtrRlocAddresses, other.rtrRlocAddresses);
Jian Li52015762016-10-04 17:51:16 +0900167 }
168 return false;
169 }
170
171 @Override
172 public String toString() {
173 return toStringHelper(this)
174 .add("Map Server UDP port number", msUdpPortNumber)
175 .add("ETR UDP port number", etrUdpPortNumber)
176 .add("global ETR RLOC address", globalEtrRlocAddress)
177 .add("Map Server RLOC address", msRlocAddress)
178 .add("private ETR RLOC address", privateEtrRlocAddress)
yoonseon980cd7c2016-11-18 14:18:46 -0800179 .add("RTR RLOC addresses", rtrRlocAddresses)
Jian Li52015762016-10-04 17:51:16 +0900180 .toString();
181 }
182
183 public static final class NatAddressBuilder extends LcafAddressBuilder<NatAddressBuilder> {
184
185 private short msUdpPortNumber;
186 private short etrUdpPortNumber;
187 private LispAfiAddress globalEtrRlocAddress;
188 private LispAfiAddress msRlocAddress;
189 private LispAfiAddress privateEtrRlocAddress;
190 private List<LispAfiAddress> rtrRlocAddresses = Lists.newArrayList();
191
192 /**
193 * Sets Map Server UDP port number.
194 *
195 * @param msUdpPortNumber Map Server UDP port number
196 * @return NatAddressBuilder object
197 */
198 public NatAddressBuilder withMsUdpPortNumber(short msUdpPortNumber) {
199 this.msUdpPortNumber = msUdpPortNumber;
200 return this;
201 }
202
203 /**
204 * Sets ETR UDP port number.
205 *
206 * @param etrUdpPortNumber ETR UDP port number
207 * @return NatAddressBuilder object
208 */
209 public NatAddressBuilder withEtrUdpPortNumber(short etrUdpPortNumber) {
210 this.etrUdpPortNumber = etrUdpPortNumber;
211 return this;
212 }
213
214 /**
215 * Sets global ETR RLOC address.
216 *
217 * @param globalEtrRlocAddress global ETR RLOC address
218 * @return NatAddressBuilder object
219 */
220 public NatAddressBuilder withGlobalEtrRlocAddress(LispAfiAddress globalEtrRlocAddress) {
221 this.globalEtrRlocAddress = globalEtrRlocAddress;
222 return this;
223 }
224
225 /**
226 * Sets Map Server RLOC address.
227 *
228 * @param msRlocAddress Map Server RLOC address
229 * @return NatAddressBuilder object
230 */
231 public NatAddressBuilder withMsRlocAddress(LispAfiAddress msRlocAddress) {
232 this.msRlocAddress = msRlocAddress;
233 return this;
234 }
235
236 /**
237 * Sets private ETR RLOC address.
238 *
239 * @param privateEtrRlocAddress private ETR RLOC address
240 * @return NatAddressBuilder object
241 */
242 public NatAddressBuilder withPrivateEtrRlocAddress(LispAfiAddress privateEtrRlocAddress) {
243 this.privateEtrRlocAddress = privateEtrRlocAddress;
244 return this;
245 }
246
247 /**
248 * Sets RTR RLOC addresses.
249 *
250 * @param rtrRlocAddresses a collection of RTR RLOC addresses
251 * @return NatAddressBuilder object
252 */
253 public NatAddressBuilder withRtrRlocAddresses(List<LispAfiAddress> rtrRlocAddresses) {
254 if (rtrRlocAddresses != null) {
255 this.rtrRlocAddresses = ImmutableList.copyOf(rtrRlocAddresses);
256 }
257 return this;
258 }
259
260 public LispNatLcafAddress build() {
261
262 // TODO: need to do null check
263
264 return new LispNatLcafAddress(reserved2, length, msUdpPortNumber,
265 etrUdpPortNumber, globalEtrRlocAddress, msRlocAddress,
266 privateEtrRlocAddress, rtrRlocAddresses);
267 }
268 }
269
270 /**
271 * NAT LCAF address reader class.
272 */
273 public static class NatLcafAddressReader
274 implements LispAddressReader<LispNatLcafAddress> {
275
276 @Override
277 public LispNatLcafAddress readFrom(ByteBuf byteBuf)
278 throws LispParseError, LispReaderException {
279
280 LispLcafAddress lcafAddress = LispLcafAddress.deserializeCommon(byteBuf);
281
282 short msUdpPortNumber = (short) byteBuf.readUnsignedShort();
283 short etrUdpPortNumber = (short) byteBuf.readUnsignedShort();
284
Jian Lief0f7232016-11-15 19:55:46 +0900285 LispAfiAddress globalEtrRlocAddress = new AfiAddressReader().readFrom(byteBuf);
286 LispAfiAddress msRlocAddress = new AfiAddressReader().readFrom(byteBuf);
287 LispAfiAddress privateEtrRlocAddress = new AfiAddressReader().readFrom(byteBuf);
Jian Li52015762016-10-04 17:51:16 +0900288
289 List<LispAfiAddress> rtrRlocAddresses = Lists.newArrayList();
Jian Lief0f7232016-11-15 19:55:46 +0900290
291 while (byteBuf.readerIndex() - LispLcafAddress.COMMON_HEADER_SIZE < lcafAddress.getLength()) {
292 rtrRlocAddresses.add(new AfiAddressReader().readFrom(byteBuf));
Jian Li52015762016-10-04 17:51:16 +0900293 }
294
295 return new NatAddressBuilder()
296 .withReserved1(lcafAddress.getReserved1())
297 .withReserved2(lcafAddress.getReserved2())
298 .withFlag(lcafAddress.getFlag())
299 .withLength(lcafAddress.getLength())
300 .withMsUdpPortNumber(msUdpPortNumber)
301 .withEtrUdpPortNumber(etrUdpPortNumber)
302 .withGlobalEtrRlocAddress(globalEtrRlocAddress)
303 .withMsRlocAddress(msRlocAddress)
304 .withPrivateEtrRlocAddress(privateEtrRlocAddress)
305 .withRtrRlocAddresses(rtrRlocAddresses).build();
306 }
307 }
308
309 /**
310 * NAT LCAF address writer class.
311 */
312 public static class NatLcafAddressWriter
313 implements LispAddressWriter<LispNatLcafAddress> {
314
315 @Override
316 public void writeTo(ByteBuf byteBuf, LispNatLcafAddress address)
317 throws LispWriterException {
318
Jian Lief0f7232016-11-15 19:55:46 +0900319 int lcafIndex = byteBuf.writerIndex();
Jian Li52015762016-10-04 17:51:16 +0900320 LispLcafAddress.serializeCommon(byteBuf, address);
321
322 byteBuf.writeShort(address.getMsUdpPortNumber());
323 byteBuf.writeShort(address.getEtrUdpPortNumber());
324
325 AfiAddressWriter writer = new LispAfiAddress.AfiAddressWriter();
326 writer.writeTo(byteBuf, address.getGlobalEtrRlocAddress());
327 writer.writeTo(byteBuf, address.getMsRlocAddress());
328 writer.writeTo(byteBuf, address.getPrivateEtrRlocAddress());
329
330 List<LispAfiAddress> rtrRlocAddresses = address.getRtrRlocAddresses();
331
332 for (int i = 0; i < rtrRlocAddresses.size(); i++) {
333 writer.writeTo(byteBuf, rtrRlocAddresses.get(i));
334 }
Jian Lief0f7232016-11-15 19:55:46 +0900335
336 LispLcafAddress.updateLength(lcafIndex, byteBuf);
Jian Li52015762016-10-04 17:51:16 +0900337 }
338 }
339}