blob: eb86b6523b17cf80f460260369d43c2de2b9aabf [file] [log] [blame]
Jian Lic7e20a52016-07-18 19:03:49 +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
Jian Lie9af3b42016-08-08 15:50:01 +090018import com.google.common.collect.ImmutableList;
Jian Li115d8602016-08-15 20:21:53 +090019import io.netty.buffer.ByteBuf;
20import org.onosproject.lisp.msg.exceptions.LispParseError;
21import org.onosproject.lisp.msg.exceptions.LispReaderException;
GUNiba871702016-08-22 21:06:02 +090022import org.onosproject.lisp.msg.exceptions.LispWriterException;
Jian Lie9af3b42016-08-08 15:50:01 +090023
Jian Lic7e20a52016-07-18 19:03:49 +090024import java.util.List;
25import java.util.Objects;
26
27import static com.google.common.base.MoreObjects.toStringHelper;
Jian Lid4e63702016-08-30 18:29:20 +090028import static com.google.common.base.Preconditions.checkArgument;
Jian Lic7e20a52016-07-18 19:03:49 +090029
30/**
31 * List type LCAF address class.
Jian Li8fc2d2f2016-08-08 14:43:53 +090032 * <p>
Jian Li89c9ca92016-11-11 04:09:02 +090033 * List type is defined in draft-ietf-lisp-lcaf-20
34 * https://tools.ietf.org/html/draft-ietf-lisp-lcaf-20#page-22
Jian Lic7e20a52016-07-18 19:03:49 +090035 *
Jian Li8fc2d2f2016-08-08 14:43:53 +090036 * <pre>
37 * {@literal
Jian Lic7e20a52016-07-18 19:03:49 +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
40 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
41 * | AFI = 16387 | Rsvd1 | Flags |
42 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Jian Li89c9ca92016-11-11 04:09:02 +090043 * | Type = 1 | Rsvd2 | Length |
Jian Lic7e20a52016-07-18 19:03:49 +090044 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
45 * | AFI = 1 | IPv4 Address ... |
46 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
47 * | ... IPv4 Address | AFI = 2 |
48 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
49 * | IPv6 Address ... |
50 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
51 * | ... IPv6 Address ... |
52 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
53 * | ... IPv6 Address ... |
54 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
55 * | ... IPv6 Address |
56 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Jian Li8fc2d2f2016-08-08 14:43:53 +090057 * }</pre>
Jian Lic7e20a52016-07-18 19:03:49 +090058 */
Jian Li115d8602016-08-15 20:21:53 +090059public final class LispListLcafAddress extends LispLcafAddress {
Jian Lic7e20a52016-07-18 19:03:49 +090060
Jian Lia7b394d2016-08-21 23:11:46 +090061 private static final short LENGTH = 24;
Jian Lic7e20a52016-07-18 19:03:49 +090062 List<LispAfiAddress> addresses;
63
64 /**
65 * Initializes list type LCAF address.
66 *
67 * @param addresses a set of IPv4 and IPv6 addresses
68 */
69 public LispListLcafAddress(List<LispAfiAddress> addresses) {
70 super(LispCanonicalAddressFormatEnum.LIST, LENGTH);
Jian Lid4e63702016-08-30 18:29:20 +090071
72 checkArgument(checkAddressValidity(addresses), "Malformed addresses, please " +
73 "specify IPv4 address first, and then specify IPv6 address");
74
Jian Lie9af3b42016-08-08 15:50:01 +090075 this.addresses = addresses;
Jian Lic7e20a52016-07-18 19:03:49 +090076 }
77
78 /**
Jian Lia7b394d2016-08-21 23:11:46 +090079 * Initializes list type LCAF address.
80 *
81 * @param reserved1 reserved1 field
Jian Li89c9ca92016-11-11 04:09:02 +090082 * @param flag flag
Jian Lia7b394d2016-08-21 23:11:46 +090083 * @param reserved2 reserved2 field
84 * @param addresses a set of IPv4 and IPv6 addresses
85 */
86 public LispListLcafAddress(byte reserved1, byte reserved2, byte flag,
87 List<LispAfiAddress> addresses) {
88 super(LispCanonicalAddressFormatEnum.LIST, reserved1, flag, reserved2, LENGTH);
Jian Lid4e63702016-08-30 18:29:20 +090089
90 checkArgument(checkAddressValidity(addresses), "Malformed addresses, please " +
91 "specify IPv4 address first, and then specify IPv6 address");
92
Jian Lia7b394d2016-08-21 23:11:46 +090093 this.addresses = addresses;
94 }
95
96 /**
Jian Lid4e63702016-08-30 18:29:20 +090097 * Checks the validity of a collection of input addresses.
98 *
99 * @param addresses a collection of addresses
100 * @return validity result
101 */
102 private boolean checkAddressValidity(List<LispAfiAddress> addresses) {
103 // we need to make sure that the address collection is comprised of
104 // one IPv4 address and one IPv6 address
105
106 if (addresses == null || addresses.size() != 2) {
107 return false;
108 }
109
110 LispAfiAddress ipv4 = addresses.get(0);
111 LispAfiAddress ipv6 = addresses.get(1);
112
113 if (ipv4.getAfi() != AddressFamilyIdentifierEnum.IP4) {
114 return false;
115 }
116
117 if (ipv6.getAfi() != AddressFamilyIdentifierEnum.IP6) {
118 return false;
119 }
120
121 return true;
122 }
123
124 /**
Jian Lic7e20a52016-07-18 19:03:49 +0900125 * Obtains a set of AFI addresses including IPv4 and IPv6.
126 *
127 * @return a set of AFI addresses
128 */
129 public List<LispAfiAddress> getAddresses() {
Jian Lie9af3b42016-08-08 15:50:01 +0900130 return ImmutableList.copyOf(addresses);
Jian Lic7e20a52016-07-18 19:03:49 +0900131 }
132
133 @Override
134 public int hashCode() {
Jian Lid56f97e2016-07-19 15:48:15 +0900135 return Objects.hash(addresses);
Jian Lic7e20a52016-07-18 19:03:49 +0900136 }
137
138 @Override
139 public boolean equals(Object obj) {
140 if (this == obj) {
141 return true;
142 }
143
144 if (obj instanceof LispListLcafAddress) {
145 final LispListLcafAddress other = (LispListLcafAddress) obj;
146 return Objects.equals(this.addresses, other.addresses);
147 }
148 return false;
149 }
150
151 @Override
152 public String toString() {
153 return toStringHelper(this)
154 .add("addresses", addresses)
155 .toString();
156 }
Jian Li115d8602016-08-15 20:21:53 +0900157
158 /**
159 * List LCAF address reader class.
160 */
161 public static class ListLcafAddressReader implements LispAddressReader<LispListLcafAddress> {
162
163 @Override
164 public LispListLcafAddress readFrom(ByteBuf byteBuf) throws LispParseError, LispReaderException {
165
Jian Lia7b394d2016-08-21 23:11:46 +0900166 LispLcafAddress lcafAddress = LispLcafAddress.deserializeCommon(byteBuf);
Jian Li115d8602016-08-15 20:21:53 +0900167
Jian Li76ea0572016-08-29 12:41:16 +0900168 AfiAddressReader reader = new AfiAddressReader();
169
170 LispAfiAddress ipv4 = reader.readFrom(byteBuf);
171 LispAfiAddress ipv6 = reader.readFrom(byteBuf);
Jian Li115d8602016-08-15 20:21:53 +0900172
Jian Lia7b394d2016-08-21 23:11:46 +0900173 return new LispListLcafAddress(lcafAddress.getReserved1(), lcafAddress.getReserved2(),
Jian Li89c9ca92016-11-11 04:09:02 +0900174 lcafAddress.getFlag(), ImmutableList.of(ipv4, ipv6));
Jian Li115d8602016-08-15 20:21:53 +0900175 }
176 }
GUNiba871702016-08-22 21:06:02 +0900177
178 /**
179 * List LCAF address writer class.
180 */
181 public static class ListLcafAddressWriter implements LispAddressWriter<LispListLcafAddress> {
182
Jian Li76ea0572016-08-29 12:41:16 +0900183 private static final int IPV4_ADDRESS_INDEX = 0;
184 private static final int IPV6_ADDRESS_INDEX = 1;
185
GUNiba871702016-08-22 21:06:02 +0900186 @Override
187 public void writeTo(ByteBuf byteBuf, LispListLcafAddress address) throws LispWriterException {
188
Jian Lief0f7232016-11-15 19:55:46 +0900189 int lcafIndex = byteBuf.writerIndex();
GUNiba871702016-08-22 21:06:02 +0900190 LispLcafAddress.serializeCommon(byteBuf, address);
191
192 LispIpv4Address.Ipv4AddressWriter v4Writer = new LispIpv4Address.Ipv4AddressWriter();
193 LispIpv6Address.Ipv6AddressWriter v6Writer = new LispIpv6Address.Ipv6AddressWriter();
194
Jian Li76ea0572016-08-29 12:41:16 +0900195 LispAfiAddress ipv4 = address.getAddresses().get(IPV4_ADDRESS_INDEX);
196 LispAfiAddress ipv6 = address.getAddresses().get(IPV6_ADDRESS_INDEX);
197
198 // IPv4 address
199 byteBuf.writeShort(ipv4.getAfi().getIanaCode());
200 v4Writer.writeTo(byteBuf, (LispIpv4Address) ipv4);
201
202 // IPv6 address
203 byteBuf.writeShort(ipv6.getAfi().getIanaCode());
204 v6Writer.writeTo(byteBuf, (LispIpv6Address) ipv6);
Jian Lief0f7232016-11-15 19:55:46 +0900205
206 LispLcafAddress.updateLength(lcafIndex, byteBuf);
GUNiba871702016-08-22 21:06:02 +0900207 }
208 }
Jian Lic7e20a52016-07-18 19:03:49 +0900209}