blob: ffea74db53c88f94231cfb6ec8aa7edbecad6ab7 [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;
24import org.onosproject.bgpio.exceptions.BGPParseException;
25import org.onosproject.bgpio.types.BGPErrorType;
26import org.onosproject.bgpio.types.BGPValueType;
27import 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 */
41public 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;
48
49 private NodeDescriptors localNodeDescriptors;
50 private NodeDescriptors remoteNodeDescriptors;
51 private List<BGPValueType> linkDescriptor;
52
53 /**
54 * Initialize fields.
55 */
56 public BGPLinkLSIdentifier() {
57 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 */
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);
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
82 * @throws BGPParseException while parsing link identifier
83 */
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);
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
94 LinkedList<BGPValueType> linkDescriptor = new LinkedList<>();
95 linkDescriptor = parseLinkDescriptors(cb);
96 return new BGPLinkLSIdentifier(localNodeDescriptors, remoteNodeDescriptors, linkDescriptor);
97 }
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
106 * @throws BGPParseException while parsing Local/Remote node descriptors
107 */
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));
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 {
123 throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.MALFORMED_ATTRIBUTE_LIST, null);
124 }
125 return nodeIdentifier;
126 }
127
128 /**
129 * Parses link descriptors.
130 *
131 * @param cb ChannelBuffer
132 * @return list of link descriptors
133 * @throws BGPParseException while parsing link descriptors
134 */
135 public static LinkedList<BGPValueType> parseLinkDescriptors(ChannelBuffer cb) throws BGPParseException {
136 LinkedList<BGPValueType> linkDescriptor = new LinkedList<>();
137 BGPValueType tlv = null;
138 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) {
145 throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.OPTIONAL_ATTRIBUTE_ERROR,
146 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
171 throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR,
172 BGPErrorType.OPTIONAL_ATTRIBUTE_ERROR, tempBuf.readBytes(length
173 + 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 */
207 public List<BGPValueType> linkDescriptors() {
208 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 }
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) {
230 return false;
231 } else {
232 while (objListIterator.hasNext() && isCommonSubTlv) {
233 BGPValueType subTlv = objListIterator.next();
234 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}