blob: e80fd13c8b797872ed6ed7aed831ec0392e2a0c3 [file] [log] [blame]
Priyanka B25fad142015-10-14 12:17:13 +05301/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
Priyanka B25fad142015-10-14 12:17:13 +05303 *
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 */
Jonathan Hart317f4762015-11-09 16:05:36 -080016package org.onosproject.bgpio.protocol.linkstate;
Priyanka B25fad142015-10-14 12:17:13 +053017
18import java.util.Iterator;
19import java.util.LinkedList;
20import java.util.List;
Priyanka B02040732015-11-29 11:30:29 +053021import java.util.ListIterator;
Priyanka B25fad142015-10-14 12:17:13 +053022import java.util.Objects;
23
24import org.jboss.netty.buffer.ChannelBuffer;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053025import org.onosproject.bgpio.exceptions.BgpParseException;
26import org.onosproject.bgpio.types.BgpErrorType;
27import org.onosproject.bgpio.types.BgpValueType;
Priyanka B25fad142015-10-14 12:17:13 +053028import org.onosproject.bgpio.types.IPv4AddressTlv;
29import org.onosproject.bgpio.types.IPv6AddressTlv;
30import org.onosproject.bgpio.types.LinkLocalRemoteIdentifiersTlv;
31import org.onosproject.bgpio.types.attr.BgpAttrNodeMultiTopologyId;
Priyanka B02040732015-11-29 11:30:29 +053032import org.onosproject.bgpio.util.Constants;
Priyanka B25fad142015-10-14 12:17:13 +053033import org.onosproject.bgpio.util.UnSupportedAttribute;
34import org.slf4j.Logger;
35import org.slf4j.LoggerFactory;
36
37import com.google.common.base.MoreObjects;
38import com.google.common.base.Preconditions;
39
40/**
41 * Implementation of local node descriptors, remote node descriptors and link descriptors.
42 */
Priyanka B02040732015-11-29 11:30:29 +053043public class BgpLinkLSIdentifier implements Comparable<Object> {
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053044 private static final Logger log = LoggerFactory.getLogger(BgpLinkLSIdentifier.class);
Priyanka B25fad142015-10-14 12:17:13 +053045 public static final short IPV4_INTERFACE_ADDRESS_TYPE = 259;
46 public static final short IPV4_NEIGHBOR_ADDRESS_TYPE = 260;
47 public static final short IPV6_INTERFACE_ADDRESS_TYPE = 261;
48 public static final short IPV6_NEIGHBOR_ADDRESS_TYPE = 262;
Priyanka B25fad142015-10-14 12:17:13 +053049
50 private NodeDescriptors localNodeDescriptors;
51 private NodeDescriptors remoteNodeDescriptors;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053052 private List<BgpValueType> linkDescriptor;
Priyanka B25fad142015-10-14 12:17:13 +053053
54 /**
55 * Initialize fields.
56 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053057 public BgpLinkLSIdentifier() {
Priyanka B25fad142015-10-14 12:17:13 +053058 this.localNodeDescriptors = null;
59 this.remoteNodeDescriptors = null;
60 this.linkDescriptor = null;
61 }
62
63 /**
64 * Constructors to initialize parameters.
65 *
66 * @param localNodeDescriptors local node descriptors
67 * @param remoteNodeDescriptors remote node descriptors
68 * @param linkDescriptor link descriptors
69 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053070 public BgpLinkLSIdentifier(NodeDescriptors localNodeDescriptors, NodeDescriptors remoteNodeDescriptors,
71 LinkedList<BgpValueType> linkDescriptor) {
Priyanka B25fad142015-10-14 12:17:13 +053072 this.localNodeDescriptors = Preconditions.checkNotNull(localNodeDescriptors);
73 this.remoteNodeDescriptors = Preconditions.checkNotNull(remoteNodeDescriptors);
74 this.linkDescriptor = Preconditions.checkNotNull(linkDescriptor);
75 }
76
77 /**
78 * Reads channel buffer and parses link identifier.
79 *
80 * @param cb ChannelBuffer
81 * @param protocolId in linkstate nlri
82 * @return object of BGPLinkLSIdentifier
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053083 * @throws BgpParseException while parsing link identifier
Priyanka B25fad142015-10-14 12:17:13 +053084 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053085 public static BgpLinkLSIdentifier parseLinkIdendifier(ChannelBuffer cb, byte protocolId) throws BgpParseException {
mohamedrahil00f6f262016-11-24 20:20:41 +053086 log.debug("Parse local node descriptor");
Priyanka B25fad142015-10-14 12:17:13 +053087 NodeDescriptors localNodeDescriptors = new NodeDescriptors();
88 localNodeDescriptors = parseNodeDescriptors(cb, NodeDescriptors.LOCAL_NODE_DES_TYPE, protocolId);
89
mohamedrahil00f6f262016-11-24 20:20:41 +053090 log.debug("Parse remote node descriptor");
Priyanka B25fad142015-10-14 12:17:13 +053091 NodeDescriptors remoteNodeDescriptors = new NodeDescriptors();
92 remoteNodeDescriptors = parseNodeDescriptors(cb, NodeDescriptors.REMOTE_NODE_DES_TYPE, protocolId);
93
mohamedrahil00f6f262016-11-24 20:20:41 +053094 log.debug("Parse link descriptor");
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053095 LinkedList<BgpValueType> linkDescriptor = new LinkedList<>();
Priyanka B25fad142015-10-14 12:17:13 +053096 linkDescriptor = parseLinkDescriptors(cb);
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053097 return new BgpLinkLSIdentifier(localNodeDescriptors, remoteNodeDescriptors, linkDescriptor);
Priyanka B25fad142015-10-14 12:17:13 +053098 }
99
100 /**
101 * Parses Local/Remote node descriptors.
102 *
103 * @param cb ChannelBuffer
104 * @param desType descriptor type
105 * @param protocolId protocol identifier
106 * @return object of NodeDescriptors
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530107 * @throws BgpParseException while parsing Local/Remote node descriptors
Priyanka B25fad142015-10-14 12:17:13 +0530108 */
109 public static NodeDescriptors parseNodeDescriptors(ChannelBuffer cb, short desType, byte protocolId)
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530110 throws BgpParseException {
mohamedrahil00f6f262016-11-24 20:20:41 +0530111 log.debug("Parse node descriptors");
Priyanka B02040732015-11-29 11:30:29 +0530112 ChannelBuffer tempBuf = cb.copy();
Priyanka B25fad142015-10-14 12:17:13 +0530113 short type = cb.readShort();
114 short length = cb.readShort();
115 if (cb.readableBytes() < length) {
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530116 throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.OPTIONAL_ATTRIBUTE_ERROR,
Priyanka B02040732015-11-29 11:30:29 +0530117 tempBuf.readBytes(cb.readableBytes() + Constants.TYPE_AND_LEN_AS_SHORT));
Priyanka B25fad142015-10-14 12:17:13 +0530118 }
119 NodeDescriptors nodeIdentifier = new NodeDescriptors();
120 ChannelBuffer tempCb = cb.readBytes(length);
121
122 if (type == desType) {
123 nodeIdentifier = NodeDescriptors.read(tempCb, length, desType, protocolId);
124 } else {
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530125 throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.MALFORMED_ATTRIBUTE_LIST, null);
Priyanka B25fad142015-10-14 12:17:13 +0530126 }
127 return nodeIdentifier;
128 }
129
130 /**
131 * Parses link descriptors.
132 *
133 * @param cb ChannelBuffer
134 * @return list of link descriptors
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530135 * @throws BgpParseException while parsing link descriptors
Priyanka B25fad142015-10-14 12:17:13 +0530136 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530137 public static LinkedList<BgpValueType> parseLinkDescriptors(ChannelBuffer cb) throws BgpParseException {
138 LinkedList<BgpValueType> linkDescriptor = new LinkedList<>();
139 BgpValueType tlv = null;
Priyanka B25fad142015-10-14 12:17:13 +0530140 int count = 0;
141
142 while (cb.readableBytes() > 0) {
Priyanka B02040732015-11-29 11:30:29 +0530143 ChannelBuffer tempBuf = cb.copy();
Priyanka B25fad142015-10-14 12:17:13 +0530144 short type = cb.readShort();
145 short length = cb.readShort();
146 if (cb.readableBytes() < length) {
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530147 throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.OPTIONAL_ATTRIBUTE_ERROR,
Priyanka B02040732015-11-29 11:30:29 +0530148 tempBuf.readBytes(cb.readableBytes() + Constants.TYPE_AND_LEN_AS_SHORT));
Priyanka B25fad142015-10-14 12:17:13 +0530149 }
150 ChannelBuffer tempCb = cb.readBytes(length);
151 switch (type) {
152 case LinkLocalRemoteIdentifiersTlv.TYPE:
153 tlv = LinkLocalRemoteIdentifiersTlv.read(tempCb);
154 break;
155 case IPV4_INTERFACE_ADDRESS_TYPE:
156 tlv = IPv4AddressTlv.read(tempCb, IPV4_INTERFACE_ADDRESS_TYPE);
157 break;
158 case IPV4_NEIGHBOR_ADDRESS_TYPE:
159 tlv = IPv4AddressTlv.read(tempCb, IPV4_NEIGHBOR_ADDRESS_TYPE);
160 break;
161 case IPV6_INTERFACE_ADDRESS_TYPE:
162 tlv = IPv6AddressTlv.read(tempCb, IPV6_INTERFACE_ADDRESS_TYPE);
163 break;
164 case IPV6_NEIGHBOR_ADDRESS_TYPE:
165 tlv = IPv6AddressTlv.read(tempCb, IPV6_NEIGHBOR_ADDRESS_TYPE);
166 break;
167 case BgpAttrNodeMultiTopologyId.ATTRNODE_MULTITOPOLOGY:
168 tlv = BgpAttrNodeMultiTopologyId.read(tempCb);
mohamedrahil00f6f262016-11-24 20:20:41 +0530169 count = count++;
170 log.debug("MultiTopologyId TLV cannot repeat more than once");
Priyanka B25fad142015-10-14 12:17:13 +0530171 if (count > 1) {
172 //length + 4 implies data contains type, length and value
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530173 throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR,
174 BgpErrorType.OPTIONAL_ATTRIBUTE_ERROR, tempBuf.readBytes(length
Priyanka B02040732015-11-29 11:30:29 +0530175 + Constants.TYPE_AND_LEN_AS_SHORT));
Priyanka B25fad142015-10-14 12:17:13 +0530176 }
177 break;
178 default:
179 UnSupportedAttribute.skipBytes(tempCb, length);
180 }
181 linkDescriptor.add(tlv);
182 }
183 return linkDescriptor;
184 }
185
186 /**
187 * Returns local node descriptors.
188 *
189 * @return local node descriptors
190 */
191 public NodeDescriptors localNodeDescriptors() {
192 return this.localNodeDescriptors;
193 }
194
195 /**
196 * Returns remote node descriptors.
197 *
198 * @return remote node descriptors
199 */
200 public NodeDescriptors remoteNodeDescriptors() {
201 return this.remoteNodeDescriptors;
202 }
203
204 /**
205 * Returns link descriptors.
206 *
207 * @return link descriptors
208 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530209 public List<BgpValueType> linkDescriptors() {
Priyanka B25fad142015-10-14 12:17:13 +0530210 return this.linkDescriptor;
211 }
212
213 @Override
214 public int hashCode() {
215 return Objects.hash(linkDescriptor, localNodeDescriptors, remoteNodeDescriptors);
216 }
217
218 @Override
219 public boolean equals(Object obj) {
220 if (this == obj) {
221 return true;
222 }
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530223 if (obj instanceof BgpLinkLSIdentifier) {
Priyanka B25fad142015-10-14 12:17:13 +0530224 int countObjSubTlv = 0;
225 int countOtherSubTlv = 0;
226 boolean isCommonSubTlv = true;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530227 BgpLinkLSIdentifier other = (BgpLinkLSIdentifier) obj;
228 Iterator<BgpValueType> objListIterator = other.linkDescriptor.iterator();
Priyanka B25fad142015-10-14 12:17:13 +0530229 countOtherSubTlv = other.linkDescriptor.size();
230 countObjSubTlv = linkDescriptor.size();
231 if (countObjSubTlv != countOtherSubTlv) {
232 return false;
233 } else {
234 while (objListIterator.hasNext() && isCommonSubTlv) {
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530235 BgpValueType subTlv = objListIterator.next();
Priyanka B02040732015-11-29 11:30:29 +0530236 if (linkDescriptor.contains(subTlv) && other.linkDescriptor.contains(subTlv)) {
237 isCommonSubTlv = Objects.equals(linkDescriptor.get(linkDescriptor.indexOf(subTlv)),
238 other.linkDescriptor.get(other.linkDescriptor.indexOf(subTlv)));
239 } else {
240 isCommonSubTlv = false;
241 }
Priyanka B25fad142015-10-14 12:17:13 +0530242 }
243 return isCommonSubTlv && Objects.equals(this.localNodeDescriptors, other.localNodeDescriptors)
244 && Objects.equals(this.remoteNodeDescriptors, other.remoteNodeDescriptors);
245 }
246 }
247 return false;
248 }
249
250 @Override
251 public String toString() {
252 return MoreObjects.toStringHelper(getClass())
253 .add("localNodeDescriptors", localNodeDescriptors)
254 .add("remoteNodeDescriptors", remoteNodeDescriptors)
255 .add("linkDescriptor", linkDescriptor)
256 .toString();
257 }
Priyanka B02040732015-11-29 11:30:29 +0530258
259 @Override
260 public int compareTo(Object o) {
261 if (this.equals(o)) {
262 return 0;
263 }
Priyanka B897c62a2015-12-13 13:37:07 +0530264 boolean tlvFound = false;
Priyanka B02040732015-11-29 11:30:29 +0530265 int result = this.localNodeDescriptors.compareTo(((BgpLinkLSIdentifier) o).localNodeDescriptors);
266 if (result != 0) {
267 return result;
268 } else if (this.remoteNodeDescriptors.compareTo(((BgpLinkLSIdentifier) o).remoteNodeDescriptors) != 0) {
269 return this.remoteNodeDescriptors.compareTo(((BgpLinkLSIdentifier) o).remoteNodeDescriptors);
270 } else {
271 int countOtherSubTlv = ((BgpLinkLSIdentifier) o).linkDescriptor.size();
272 int countObjSubTlv = linkDescriptor.size();
273 if (countOtherSubTlv != countObjSubTlv) {
274 if (countOtherSubTlv > countObjSubTlv) {
275 return 1;
276 } else {
277 return -1;
278 }
Priyanka B897c62a2015-12-13 13:37:07 +0530279 }
Priyanka B02040732015-11-29 11:30:29 +0530280 ListIterator<BgpValueType> listIterator = linkDescriptor.listIterator();
Priyanka B02040732015-11-29 11:30:29 +0530281 while (listIterator.hasNext()) {
Priyanka B897c62a2015-12-13 13:37:07 +0530282 BgpValueType tlv1 = listIterator.next();
283 for (BgpValueType tlv : ((BgpLinkLSIdentifier) o).linkDescriptor) {
284 if (tlv.getType() == tlv1.getType()) {
285 result = linkDescriptor.get(linkDescriptor.indexOf(tlv1)).compareTo(
286 ((BgpLinkLSIdentifier) o).linkDescriptor.get(((BgpLinkLSIdentifier) o).linkDescriptor
287 .indexOf(tlv)));
288 if (result != 0) {
289 return result;
290 }
291 tlvFound = true;
292 break;
Priyanka B02040732015-11-29 11:30:29 +0530293 }
Priyanka B897c62a2015-12-13 13:37:07 +0530294 }
295 if (!tlvFound) {
Shashikanth VHeacbed52015-12-02 22:37:21 +0530296 return 1;
Priyanka B02040732015-11-29 11:30:29 +0530297 }
298 }
299 }
300 return 0;
301 }
Jonathan Hart317f4762015-11-09 16:05:36 -0800302}