2 * Copyright 2015 Open Networking Laboratory
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package org.onosproject.bgpio.protocol.linkstate;
18 import java.util.Iterator;
19 import java.util.LinkedList;
20 import java.util.List;
21 import java.util.ListIterator;
22 import java.util.Objects;
24 import org.jboss.netty.buffer.ChannelBuffer;
25 import org.onosproject.bgpio.exceptions.BgpParseException;
26 import org.onosproject.bgpio.types.BgpErrorType;
27 import org.onosproject.bgpio.types.BgpValueType;
28 import org.onosproject.bgpio.types.IPv4AddressTlv;
29 import org.onosproject.bgpio.types.IPv6AddressTlv;
30 import org.onosproject.bgpio.types.LinkLocalRemoteIdentifiersTlv;
31 import org.onosproject.bgpio.types.attr.BgpAttrNodeMultiTopologyId;
32 import org.onosproject.bgpio.util.Constants;
33 import org.onosproject.bgpio.util.UnSupportedAttribute;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
37 import com.google.common.base.MoreObjects;
38 import com.google.common.base.Preconditions;
41 * Implementation of local node descriptors, remote node descriptors and link descriptors.
43 public class BgpLinkLSIdentifier implements Comparable<Object> {
44 private static final Logger log = LoggerFactory.getLogger(BgpLinkLSIdentifier.class);
45 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;
50 private NodeDescriptors localNodeDescriptors;
51 private NodeDescriptors remoteNodeDescriptors;
52 private List<BgpValueType> linkDescriptor;
57 public BgpLinkLSIdentifier() {
58 this.localNodeDescriptors = null;
59 this.remoteNodeDescriptors = null;
60 this.linkDescriptor = null;
64 * Constructors to initialize parameters.
66 * @param localNodeDescriptors local node descriptors
67 * @param remoteNodeDescriptors remote node descriptors
68 * @param linkDescriptor link descriptors
70 public BgpLinkLSIdentifier(NodeDescriptors localNodeDescriptors, NodeDescriptors remoteNodeDescriptors,
71 LinkedList<BgpValueType> linkDescriptor) {
72 this.localNodeDescriptors = Preconditions.checkNotNull(localNodeDescriptors);
73 this.remoteNodeDescriptors = Preconditions.checkNotNull(remoteNodeDescriptors);
74 this.linkDescriptor = Preconditions.checkNotNull(linkDescriptor);
78 * Reads channel buffer and parses link identifier.
80 * @param cb ChannelBuffer
81 * @param protocolId in linkstate nlri
82 * @return object of BGPLinkLSIdentifier
83 * @throws BgpParseException while parsing link identifier
85 public static BgpLinkLSIdentifier parseLinkIdendifier(ChannelBuffer cb, byte protocolId) throws BgpParseException {
86 //Parse local node descriptor
87 NodeDescriptors localNodeDescriptors = new NodeDescriptors();
88 localNodeDescriptors = parseNodeDescriptors(cb, NodeDescriptors.LOCAL_NODE_DES_TYPE, protocolId);
90 //Parse remote node descriptor
91 NodeDescriptors remoteNodeDescriptors = new NodeDescriptors();
92 remoteNodeDescriptors = parseNodeDescriptors(cb, NodeDescriptors.REMOTE_NODE_DES_TYPE, protocolId);
94 //Parse link descriptor
95 LinkedList<BgpValueType> linkDescriptor = new LinkedList<>();
96 linkDescriptor = parseLinkDescriptors(cb);
97 return new BgpLinkLSIdentifier(localNodeDescriptors, remoteNodeDescriptors, linkDescriptor);
101 * Parses Local/Remote node descriptors.
103 * @param cb ChannelBuffer
104 * @param desType descriptor type
105 * @param protocolId protocol identifier
106 * @return object of NodeDescriptors
107 * @throws BgpParseException while parsing Local/Remote node descriptors
109 public static NodeDescriptors parseNodeDescriptors(ChannelBuffer cb, short desType, byte protocolId)
110 throws BgpParseException {
111 log.debug("parse Node descriptors");
112 ChannelBuffer tempBuf = cb.copy();
113 short type = cb.readShort();
114 short length = cb.readShort();
115 if (cb.readableBytes() < length) {
116 throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.OPTIONAL_ATTRIBUTE_ERROR,
117 tempBuf.readBytes(cb.readableBytes() + Constants.TYPE_AND_LEN_AS_SHORT));
119 NodeDescriptors nodeIdentifier = new NodeDescriptors();
120 ChannelBuffer tempCb = cb.readBytes(length);
122 if (type == desType) {
123 nodeIdentifier = NodeDescriptors.read(tempCb, length, desType, protocolId);
125 throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.MALFORMED_ATTRIBUTE_LIST, null);
127 return nodeIdentifier;
131 * Parses link descriptors.
133 * @param cb ChannelBuffer
134 * @return list of link descriptors
135 * @throws BgpParseException while parsing link descriptors
137 public static LinkedList<BgpValueType> parseLinkDescriptors(ChannelBuffer cb) throws BgpParseException {
138 LinkedList<BgpValueType> linkDescriptor = new LinkedList<>();
139 BgpValueType tlv = null;
142 while (cb.readableBytes() > 0) {
143 ChannelBuffer tempBuf = cb.copy();
144 short type = cb.readShort();
145 short length = cb.readShort();
146 if (cb.readableBytes() < length) {
147 throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.OPTIONAL_ATTRIBUTE_ERROR,
148 tempBuf.readBytes(cb.readableBytes() + Constants.TYPE_AND_LEN_AS_SHORT));
150 ChannelBuffer tempCb = cb.readBytes(length);
152 case LinkLocalRemoteIdentifiersTlv.TYPE:
153 tlv = LinkLocalRemoteIdentifiersTlv.read(tempCb);
155 case IPV4_INTERFACE_ADDRESS_TYPE:
156 tlv = IPv4AddressTlv.read(tempCb, IPV4_INTERFACE_ADDRESS_TYPE);
158 case IPV4_NEIGHBOR_ADDRESS_TYPE:
159 tlv = IPv4AddressTlv.read(tempCb, IPV4_NEIGHBOR_ADDRESS_TYPE);
161 case IPV6_INTERFACE_ADDRESS_TYPE:
162 tlv = IPv6AddressTlv.read(tempCb, IPV6_INTERFACE_ADDRESS_TYPE);
164 case IPV6_NEIGHBOR_ADDRESS_TYPE:
165 tlv = IPv6AddressTlv.read(tempCb, IPV6_NEIGHBOR_ADDRESS_TYPE);
167 case BgpAttrNodeMultiTopologyId.ATTRNODE_MULTITOPOLOGY:
168 tlv = BgpAttrNodeMultiTopologyId.read(tempCb);
170 //MultiTopologyId TLV cannot repeat more than once
172 //length + 4 implies data contains type, length and value
173 throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR,
174 BgpErrorType.OPTIONAL_ATTRIBUTE_ERROR, tempBuf.readBytes(length
175 + Constants.TYPE_AND_LEN_AS_SHORT));
179 UnSupportedAttribute.skipBytes(tempCb, length);
181 linkDescriptor.add(tlv);
183 return linkDescriptor;
187 * Returns local node descriptors.
189 * @return local node descriptors
191 public NodeDescriptors localNodeDescriptors() {
192 return this.localNodeDescriptors;
196 * Returns remote node descriptors.
198 * @return remote node descriptors
200 public NodeDescriptors remoteNodeDescriptors() {
201 return this.remoteNodeDescriptors;
205 * Returns link descriptors.
207 * @return link descriptors
209 public List<BgpValueType> linkDescriptors() {
210 return this.linkDescriptor;
214 public int hashCode() {
215 return Objects.hash(linkDescriptor, localNodeDescriptors, remoteNodeDescriptors);
219 public boolean equals(Object obj) {
223 if (obj instanceof BgpLinkLSIdentifier) {
224 int countObjSubTlv = 0;
225 int countOtherSubTlv = 0;
226 boolean isCommonSubTlv = true;
227 BgpLinkLSIdentifier other = (BgpLinkLSIdentifier) obj;
228 Iterator<BgpValueType> objListIterator = other.linkDescriptor.iterator();
229 countOtherSubTlv = other.linkDescriptor.size();
230 countObjSubTlv = linkDescriptor.size();
231 if (countObjSubTlv != countOtherSubTlv) {
234 while (objListIterator.hasNext() && isCommonSubTlv) {
235 BgpValueType subTlv = objListIterator.next();
236 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)));
240 isCommonSubTlv = false;
243 return isCommonSubTlv && Objects.equals(this.localNodeDescriptors, other.localNodeDescriptors)
244 && Objects.equals(this.remoteNodeDescriptors, other.remoteNodeDescriptors);
251 public String toString() {
252 return MoreObjects.toStringHelper(getClass())
253 .add("localNodeDescriptors", localNodeDescriptors)
254 .add("remoteNodeDescriptors", remoteNodeDescriptors)
255 .add("linkDescriptor", linkDescriptor)
260 public int compareTo(Object o) {
261 if (this.equals(o)) {
264 int result = this.localNodeDescriptors.compareTo(((BgpLinkLSIdentifier) o).localNodeDescriptors);
267 } else if (this.remoteNodeDescriptors.compareTo(((BgpLinkLSIdentifier) o).remoteNodeDescriptors) != 0) {
268 return this.remoteNodeDescriptors.compareTo(((BgpLinkLSIdentifier) o).remoteNodeDescriptors);
270 int countOtherSubTlv = ((BgpLinkLSIdentifier) o).linkDescriptor.size();
271 int countObjSubTlv = linkDescriptor.size();
272 if (countOtherSubTlv != countObjSubTlv) {
273 if (countOtherSubTlv > countObjSubTlv) {
279 ListIterator<BgpValueType> listIterator = linkDescriptor.listIterator();
280 ListIterator<BgpValueType> listIteratorOther = ((BgpLinkLSIdentifier) o).linkDescriptor.listIterator();
281 while (listIterator.hasNext()) {
282 BgpValueType tlv = listIterator.next();
283 BgpValueType tlv1 = listIteratorOther.next();
284 if (linkDescriptor.contains(tlv) && ((BgpLinkLSIdentifier) o).linkDescriptor.contains(tlv1)) {
285 int res = linkDescriptor.get(linkDescriptor.indexOf(tlv)).compareTo(
286 ((BgpLinkLSIdentifier) o).linkDescriptor.get(((BgpLinkLSIdentifier) o).linkDescriptor