blob: 9b14b4be3a51e28544a264cf10012261a71c37f4 [file] [log] [blame]
Priyanka B25fad142015-10-14 12:17:13 +05301/*
2 * Copyright 2015 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 */
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;
21import java.util.Objects;
22
23import org.jboss.netty.buffer.ChannelBuffer;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053024import org.onosproject.bgpio.exceptions.BgpParseException;
25import org.onosproject.bgpio.types.BgpErrorType;
26import org.onosproject.bgpio.types.BgpValueType;
Priyanka B25fad142015-10-14 12:17:13 +053027import org.onosproject.bgpio.types.IPv4AddressTlv;
28import org.onosproject.bgpio.types.IPv6AddressTlv;
29import org.onosproject.bgpio.types.LinkLocalRemoteIdentifiersTlv;
30import org.onosproject.bgpio.types.attr.BgpAttrNodeMultiTopologyId;
31import org.onosproject.bgpio.util.UnSupportedAttribute;
32import org.slf4j.Logger;
33import org.slf4j.LoggerFactory;
34
35import com.google.common.base.MoreObjects;
36import com.google.common.base.Preconditions;
37
38/**
39 * Implementation of local node descriptors, remote node descriptors and link descriptors.
40 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053041public class BgpLinkLSIdentifier {
42 private static final Logger log = LoggerFactory.getLogger(BgpLinkLSIdentifier.class);
Priyanka B25fad142015-10-14 12:17:13 +053043 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;
48
49 private NodeDescriptors localNodeDescriptors;
50 private NodeDescriptors remoteNodeDescriptors;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053051 private List<BgpValueType> linkDescriptor;
Priyanka B25fad142015-10-14 12:17:13 +053052
53 /**
54 * Initialize fields.
55 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053056 public BgpLinkLSIdentifier() {
Priyanka B25fad142015-10-14 12:17:13 +053057 this.localNodeDescriptors = null;
58 this.remoteNodeDescriptors = null;
59 this.linkDescriptor = null;
60 }
61
62 /**
63 * Constructors to initialize parameters.
64 *
65 * @param localNodeDescriptors local node descriptors
66 * @param remoteNodeDescriptors remote node descriptors
67 * @param linkDescriptor link descriptors
68 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053069 public BgpLinkLSIdentifier(NodeDescriptors localNodeDescriptors, NodeDescriptors remoteNodeDescriptors,
70 LinkedList<BgpValueType> linkDescriptor) {
Priyanka B25fad142015-10-14 12:17:13 +053071 this.localNodeDescriptors = Preconditions.checkNotNull(localNodeDescriptors);
72 this.remoteNodeDescriptors = Preconditions.checkNotNull(remoteNodeDescriptors);
73 this.linkDescriptor = Preconditions.checkNotNull(linkDescriptor);
74 }
75
76 /**
77 * Reads channel buffer and parses link identifier.
78 *
79 * @param cb ChannelBuffer
80 * @param protocolId in linkstate nlri
81 * @return object of BGPLinkLSIdentifier
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053082 * @throws BgpParseException while parsing link identifier
Priyanka B25fad142015-10-14 12:17:13 +053083 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053084 public static BgpLinkLSIdentifier parseLinkIdendifier(ChannelBuffer cb, byte protocolId) throws BgpParseException {
Priyanka B25fad142015-10-14 12:17:13 +053085 //Parse local node descriptor
86 NodeDescriptors localNodeDescriptors = new NodeDescriptors();
87 localNodeDescriptors = parseNodeDescriptors(cb, NodeDescriptors.LOCAL_NODE_DES_TYPE, protocolId);
88
89 //Parse remote node descriptor
90 NodeDescriptors remoteNodeDescriptors = new NodeDescriptors();
91 remoteNodeDescriptors = parseNodeDescriptors(cb, NodeDescriptors.REMOTE_NODE_DES_TYPE, protocolId);
92
93 //Parse link descriptor
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053094 LinkedList<BgpValueType> linkDescriptor = new LinkedList<>();
Priyanka B25fad142015-10-14 12:17:13 +053095 linkDescriptor = parseLinkDescriptors(cb);
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053096 return new BgpLinkLSIdentifier(localNodeDescriptors, remoteNodeDescriptors, linkDescriptor);
Priyanka B25fad142015-10-14 12:17:13 +053097 }
98
99 /**
100 * Parses Local/Remote node descriptors.
101 *
102 * @param cb ChannelBuffer
103 * @param desType descriptor type
104 * @param protocolId protocol identifier
105 * @return object of NodeDescriptors
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530106 * @throws BgpParseException while parsing Local/Remote node descriptors
Priyanka B25fad142015-10-14 12:17:13 +0530107 */
108 public static NodeDescriptors parseNodeDescriptors(ChannelBuffer cb, short desType, byte protocolId)
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530109 throws BgpParseException {
Priyanka B25fad142015-10-14 12:17:13 +0530110 ChannelBuffer tempBuf = cb;
111 short type = cb.readShort();
112 short length = cb.readShort();
113 if (cb.readableBytes() < length) {
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530114 throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.OPTIONAL_ATTRIBUTE_ERROR,
Priyanka B25fad142015-10-14 12:17:13 +0530115 tempBuf.readBytes(cb.readableBytes() + TYPE_AND_LEN));
116 }
117 NodeDescriptors nodeIdentifier = new NodeDescriptors();
118 ChannelBuffer tempCb = cb.readBytes(length);
119
120 if (type == desType) {
121 nodeIdentifier = NodeDescriptors.read(tempCb, length, desType, protocolId);
122 } else {
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530123 throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.MALFORMED_ATTRIBUTE_LIST, null);
Priyanka B25fad142015-10-14 12:17:13 +0530124 }
125 return nodeIdentifier;
126 }
127
128 /**
129 * Parses link descriptors.
130 *
131 * @param cb ChannelBuffer
132 * @return list of link descriptors
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530133 * @throws BgpParseException while parsing link descriptors
Priyanka B25fad142015-10-14 12:17:13 +0530134 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530135 public static LinkedList<BgpValueType> parseLinkDescriptors(ChannelBuffer cb) throws BgpParseException {
136 LinkedList<BgpValueType> linkDescriptor = new LinkedList<>();
137 BgpValueType tlv = null;
Priyanka B25fad142015-10-14 12:17:13 +0530138 int count = 0;
139
140 while (cb.readableBytes() > 0) {
141 ChannelBuffer tempBuf = cb;
142 short type = cb.readShort();
143 short length = cb.readShort();
144 if (cb.readableBytes() < length) {
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530145 throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.OPTIONAL_ATTRIBUTE_ERROR,
Priyanka B25fad142015-10-14 12:17:13 +0530146 tempBuf.readBytes(cb.readableBytes() + TYPE_AND_LEN));
147 }
148 ChannelBuffer tempCb = cb.readBytes(length);
149 switch (type) {
150 case LinkLocalRemoteIdentifiersTlv.TYPE:
151 tlv = LinkLocalRemoteIdentifiersTlv.read(tempCb);
152 break;
153 case IPV4_INTERFACE_ADDRESS_TYPE:
154 tlv = IPv4AddressTlv.read(tempCb, IPV4_INTERFACE_ADDRESS_TYPE);
155 break;
156 case IPV4_NEIGHBOR_ADDRESS_TYPE:
157 tlv = IPv4AddressTlv.read(tempCb, IPV4_NEIGHBOR_ADDRESS_TYPE);
158 break;
159 case IPV6_INTERFACE_ADDRESS_TYPE:
160 tlv = IPv6AddressTlv.read(tempCb, IPV6_INTERFACE_ADDRESS_TYPE);
161 break;
162 case IPV6_NEIGHBOR_ADDRESS_TYPE:
163 tlv = IPv6AddressTlv.read(tempCb, IPV6_NEIGHBOR_ADDRESS_TYPE);
164 break;
165 case BgpAttrNodeMultiTopologyId.ATTRNODE_MULTITOPOLOGY:
166 tlv = BgpAttrNodeMultiTopologyId.read(tempCb);
167 count = count++;
168 //MultiTopologyId TLV cannot repeat more than once
169 if (count > 1) {
170 //length + 4 implies data contains type, length and value
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530171 throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR,
172 BgpErrorType.OPTIONAL_ATTRIBUTE_ERROR, tempBuf.readBytes(length
Priyanka B25fad142015-10-14 12:17:13 +0530173 + TYPE_AND_LEN));
174 }
175 break;
176 default:
177 UnSupportedAttribute.skipBytes(tempCb, length);
178 }
179 linkDescriptor.add(tlv);
180 }
181 return linkDescriptor;
182 }
183
184 /**
185 * Returns local node descriptors.
186 *
187 * @return local node descriptors
188 */
189 public NodeDescriptors localNodeDescriptors() {
190 return this.localNodeDescriptors;
191 }
192
193 /**
194 * Returns remote node descriptors.
195 *
196 * @return remote node descriptors
197 */
198 public NodeDescriptors remoteNodeDescriptors() {
199 return this.remoteNodeDescriptors;
200 }
201
202 /**
203 * Returns link descriptors.
204 *
205 * @return link descriptors
206 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530207 public List<BgpValueType> linkDescriptors() {
Priyanka B25fad142015-10-14 12:17:13 +0530208 return this.linkDescriptor;
209 }
210
211 @Override
212 public int hashCode() {
213 return Objects.hash(linkDescriptor, localNodeDescriptors, remoteNodeDescriptors);
214 }
215
216 @Override
217 public boolean equals(Object obj) {
218 if (this == obj) {
219 return true;
220 }
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530221 if (obj instanceof BgpLinkLSIdentifier) {
Priyanka B25fad142015-10-14 12:17:13 +0530222 int countObjSubTlv = 0;
223 int countOtherSubTlv = 0;
224 boolean isCommonSubTlv = true;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530225 BgpLinkLSIdentifier other = (BgpLinkLSIdentifier) obj;
226 Iterator<BgpValueType> objListIterator = other.linkDescriptor.iterator();
Priyanka B25fad142015-10-14 12:17:13 +0530227 countOtherSubTlv = other.linkDescriptor.size();
228 countObjSubTlv = linkDescriptor.size();
229 if (countObjSubTlv != countOtherSubTlv) {
230 return false;
231 } else {
232 while (objListIterator.hasNext() && isCommonSubTlv) {
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530233 BgpValueType subTlv = objListIterator.next();
Priyanka B25fad142015-10-14 12:17:13 +0530234 isCommonSubTlv = Objects.equals(linkDescriptor.contains(subTlv),
235 other.linkDescriptor.contains(subTlv));
236 }
237 return isCommonSubTlv && Objects.equals(this.localNodeDescriptors, other.localNodeDescriptors)
238 && Objects.equals(this.remoteNodeDescriptors, other.remoteNodeDescriptors);
239 }
240 }
241 return false;
242 }
243
244 @Override
245 public String toString() {
246 return MoreObjects.toStringHelper(getClass())
247 .add("localNodeDescriptors", localNodeDescriptors)
248 .add("remoteNodeDescriptors", remoteNodeDescriptors)
249 .add("linkDescriptor", linkDescriptor)
250 .toString();
251 }
Jonathan Hart317f4762015-11-09 16:05:36 -0800252}