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.link_state;
18 import java.util.Iterator;
19 import java.util.LinkedList;
20 import java.util.List;
21 import java.util.Objects;
23 import org.jboss.netty.buffer.ChannelBuffer;
24 import org.onosproject.bgpio.exceptions.BGPParseException;
25 import org.onosproject.bgpio.types.BGPErrorType;
26 import org.onosproject.bgpio.types.BGPValueType;
27 import org.onosproject.bgpio.types.IPv4AddressTlv;
28 import org.onosproject.bgpio.types.IPv6AddressTlv;
29 import org.onosproject.bgpio.types.LinkLocalRemoteIdentifiersTlv;
30 import org.onosproject.bgpio.types.attr.BgpAttrNodeMultiTopologyId;
31 import org.onosproject.bgpio.util.UnSupportedAttribute;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
35 import com.google.common.base.MoreObjects;
36 import com.google.common.base.Preconditions;
39 * Implementation of local node descriptors, remote node descriptors and link descriptors.
41 public class BGPLinkLSIdentifier {
42 private static final Logger log = LoggerFactory.getLogger(BGPLinkLSIdentifier.class);
43 public static final short IPV4_INTERFACE_ADDRESS_TYPE = 259;
44 public static final short IPV4_NEIGHBOR_ADDRESS_TYPE = 260;
45 public static final short IPV6_INTERFACE_ADDRESS_TYPE = 261;
46 public static final short IPV6_NEIGHBOR_ADDRESS_TYPE = 262;
47 public static final int TYPE_AND_LEN = 4;
49 private NodeDescriptors localNodeDescriptors;
50 private NodeDescriptors remoteNodeDescriptors;
51 private List<BGPValueType> linkDescriptor;
56 public BGPLinkLSIdentifier() {
57 this.localNodeDescriptors = null;
58 this.remoteNodeDescriptors = null;
59 this.linkDescriptor = null;
63 * Constructors to initialize parameters.
65 * @param localNodeDescriptors local node descriptors
66 * @param remoteNodeDescriptors remote node descriptors
67 * @param linkDescriptor link descriptors
69 public BGPLinkLSIdentifier(NodeDescriptors localNodeDescriptors, NodeDescriptors remoteNodeDescriptors,
70 LinkedList<BGPValueType> linkDescriptor) {
71 this.localNodeDescriptors = Preconditions.checkNotNull(localNodeDescriptors);
72 this.remoteNodeDescriptors = Preconditions.checkNotNull(remoteNodeDescriptors);
73 this.linkDescriptor = Preconditions.checkNotNull(linkDescriptor);
77 * Reads channel buffer and parses link identifier.
79 * @param cb ChannelBuffer
80 * @param protocolId in linkstate nlri
81 * @return object of BGPLinkLSIdentifier
82 * @throws BGPParseException while parsing link identifier
84 public static BGPLinkLSIdentifier parseLinkIdendifier(ChannelBuffer cb, byte protocolId) throws BGPParseException {
85 //Parse local node descriptor
86 NodeDescriptors localNodeDescriptors = new NodeDescriptors();
87 localNodeDescriptors = parseNodeDescriptors(cb, NodeDescriptors.LOCAL_NODE_DES_TYPE, protocolId);
89 //Parse remote node descriptor
90 NodeDescriptors remoteNodeDescriptors = new NodeDescriptors();
91 remoteNodeDescriptors = parseNodeDescriptors(cb, NodeDescriptors.REMOTE_NODE_DES_TYPE, protocolId);
93 //Parse link descriptor
94 LinkedList<BGPValueType> linkDescriptor = new LinkedList<>();
95 linkDescriptor = parseLinkDescriptors(cb);
96 return new BGPLinkLSIdentifier(localNodeDescriptors, remoteNodeDescriptors, linkDescriptor);
100 * Parses Local/Remote node descriptors.
102 * @param cb ChannelBuffer
103 * @param desType descriptor type
104 * @param protocolId protocol identifier
105 * @return object of NodeDescriptors
106 * @throws BGPParseException while parsing Local/Remote node descriptors
108 public static NodeDescriptors parseNodeDescriptors(ChannelBuffer cb, short desType, byte protocolId)
109 throws BGPParseException {
110 ChannelBuffer tempBuf = cb;
111 short type = cb.readShort();
112 short length = cb.readShort();
113 if (cb.readableBytes() < length) {
114 throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.OPTIONAL_ATTRIBUTE_ERROR,
115 tempBuf.readBytes(cb.readableBytes() + TYPE_AND_LEN));
117 NodeDescriptors nodeIdentifier = new NodeDescriptors();
118 ChannelBuffer tempCb = cb.readBytes(length);
120 if (type == desType) {
121 nodeIdentifier = NodeDescriptors.read(tempCb, length, desType, protocolId);
123 throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.MALFORMED_ATTRIBUTE_LIST, null);
125 return nodeIdentifier;
129 * Parses link descriptors.
131 * @param cb ChannelBuffer
132 * @return list of link descriptors
133 * @throws BGPParseException while parsing link descriptors
135 public static LinkedList<BGPValueType> parseLinkDescriptors(ChannelBuffer cb) throws BGPParseException {
136 LinkedList<BGPValueType> linkDescriptor = new LinkedList<>();
137 BGPValueType tlv = null;
140 while (cb.readableBytes() > 0) {
141 ChannelBuffer tempBuf = cb;
142 short type = cb.readShort();
143 short length = cb.readShort();
144 if (cb.readableBytes() < length) {
145 throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.OPTIONAL_ATTRIBUTE_ERROR,
146 tempBuf.readBytes(cb.readableBytes() + TYPE_AND_LEN));
148 ChannelBuffer tempCb = cb.readBytes(length);
150 case LinkLocalRemoteIdentifiersTlv.TYPE:
151 tlv = LinkLocalRemoteIdentifiersTlv.read(tempCb);
153 case IPV4_INTERFACE_ADDRESS_TYPE:
154 tlv = IPv4AddressTlv.read(tempCb, IPV4_INTERFACE_ADDRESS_TYPE);
156 case IPV4_NEIGHBOR_ADDRESS_TYPE:
157 tlv = IPv4AddressTlv.read(tempCb, IPV4_NEIGHBOR_ADDRESS_TYPE);
159 case IPV6_INTERFACE_ADDRESS_TYPE:
160 tlv = IPv6AddressTlv.read(tempCb, IPV6_INTERFACE_ADDRESS_TYPE);
162 case IPV6_NEIGHBOR_ADDRESS_TYPE:
163 tlv = IPv6AddressTlv.read(tempCb, IPV6_NEIGHBOR_ADDRESS_TYPE);
165 case BgpAttrNodeMultiTopologyId.ATTRNODE_MULTITOPOLOGY:
166 tlv = BgpAttrNodeMultiTopologyId.read(tempCb);
168 //MultiTopologyId TLV cannot repeat more than once
170 //length + 4 implies data contains type, length and value
171 throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR,
172 BGPErrorType.OPTIONAL_ATTRIBUTE_ERROR, tempBuf.readBytes(length
177 UnSupportedAttribute.skipBytes(tempCb, length);
179 linkDescriptor.add(tlv);
181 return linkDescriptor;
185 * Returns local node descriptors.
187 * @return local node descriptors
189 public NodeDescriptors localNodeDescriptors() {
190 return this.localNodeDescriptors;
194 * Returns remote node descriptors.
196 * @return remote node descriptors
198 public NodeDescriptors remoteNodeDescriptors() {
199 return this.remoteNodeDescriptors;
203 * Returns link descriptors.
205 * @return link descriptors
207 public List<BGPValueType> linkDescriptors() {
208 return this.linkDescriptor;
212 public int hashCode() {
213 return Objects.hash(linkDescriptor, localNodeDescriptors, remoteNodeDescriptors);
217 public boolean equals(Object obj) {
221 if (obj instanceof BGPLinkLSIdentifier) {
222 int countObjSubTlv = 0;
223 int countOtherSubTlv = 0;
224 boolean isCommonSubTlv = true;
225 BGPLinkLSIdentifier other = (BGPLinkLSIdentifier) obj;
226 Iterator<BGPValueType> objListIterator = other.linkDescriptor.iterator();
227 countOtherSubTlv = other.linkDescriptor.size();
228 countObjSubTlv = linkDescriptor.size();
229 if (countObjSubTlv != countOtherSubTlv) {
232 while (objListIterator.hasNext() && isCommonSubTlv) {
233 BGPValueType subTlv = objListIterator.next();
234 isCommonSubTlv = Objects.equals(linkDescriptor.contains(subTlv),
235 other.linkDescriptor.contains(subTlv));
237 return isCommonSubTlv && Objects.equals(this.localNodeDescriptors, other.localNodeDescriptors)
238 && Objects.equals(this.remoteNodeDescriptors, other.remoteNodeDescriptors);
245 public String toString() {
246 return MoreObjects.toStringHelper(getClass())
247 .add("localNodeDescriptors", localNodeDescriptors)
248 .add("remoteNodeDescriptors", remoteNodeDescriptors)
249 .add("linkDescriptor", linkDescriptor)