blob: eb795b462dac6d93b345b8f5945ddc2c3d894911 [file] [log] [blame]
Priyanka Bb2988fa2015-10-09 12:45:36 +05301/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
Priyanka Bb2988fa2015-10-09 12:45:36 +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 */
16
Jonathan Hart317f4762015-11-09 16:05:36 -080017package org.onosproject.bgpio.protocol.linkstate;
Priyanka Bb2988fa2015-10-09 12:45:36 +053018
19import java.util.Iterator;
20import java.util.LinkedList;
Priyanka B02040732015-11-29 11:30:29 +053021import java.util.List;
22import java.util.ListIterator;
Priyanka Bb2988fa2015-10-09 12:45:36 +053023import java.util.Objects;
24
25import org.jboss.netty.buffer.ChannelBuffer;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053026import org.onosproject.bgpio.exceptions.BgpParseException;
27import org.onosproject.bgpio.types.BgpErrorType;
28import org.onosproject.bgpio.types.BgpValueType;
Priyanka Bb2988fa2015-10-09 12:45:36 +053029import org.onosproject.bgpio.types.IPReachabilityInformationTlv;
Jonathan Hart51539b82015-10-29 09:53:04 -070030import org.onosproject.bgpio.types.OspfRouteTypeTlv;
Priyanka Bb2988fa2015-10-09 12:45:36 +053031import org.onosproject.bgpio.types.attr.BgpAttrNodeMultiTopologyId;
32import org.onosproject.bgpio.util.UnSupportedAttribute;
33import org.slf4j.Logger;
34import org.slf4j.LoggerFactory;
35
36import com.google.common.base.MoreObjects;
37
38/**
39 * Provides Implementation of Local node descriptors and prefix descriptors.
40 */
Priyanka B02040732015-11-29 11:30:29 +053041public class BgpPrefixLSIdentifier implements Comparable<Object> {
Priyanka Bb2988fa2015-10-09 12:45:36 +053042
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053043 protected static final Logger log = LoggerFactory.getLogger(BgpPrefixLSIdentifier.class);
Priyanka Bb2988fa2015-10-09 12:45:36 +053044 public static final int TYPE_AND_LEN = 4;
45 private NodeDescriptors localNodeDescriptors;
Priyanka B02040732015-11-29 11:30:29 +053046 private List<BgpValueType> prefixDescriptor;
Priyanka Bb2988fa2015-10-09 12:45:36 +053047
48 /**
49 * Resets parameters.
50 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053051 public BgpPrefixLSIdentifier() {
Priyanka Bb2988fa2015-10-09 12:45:36 +053052 this.localNodeDescriptors = null;
53 this.prefixDescriptor = null;
mohamedrahil00f6f262016-11-24 20:20:41 +053054 log.debug("Parameters are reset");
Priyanka Bb2988fa2015-10-09 12:45:36 +053055 }
56
57 /**
58 * Constructor to initialize parameters.
59 *
60 * @param localNodeDescriptors Local node descriptors
61 * @param prefixDescriptor Prefix Descriptors
62 */
Priyanka B02040732015-11-29 11:30:29 +053063 public BgpPrefixLSIdentifier(NodeDescriptors localNodeDescriptors, List<BgpValueType> prefixDescriptor) {
Priyanka Bb2988fa2015-10-09 12:45:36 +053064 this.localNodeDescriptors = localNodeDescriptors;
65 this.prefixDescriptor = prefixDescriptor;
66 }
67
68 /**
69 * Reads the channel buffer and parses Prefix Identifier.
70 *
71 * @param cb ChannelBuffer
72 * @param protocolId protocol ID
73 * @return object of this class
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053074 * @throws BgpParseException while parsing Prefix Identifier
Priyanka Bb2988fa2015-10-09 12:45:36 +053075 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053076 public static BgpPrefixLSIdentifier parsePrefixIdendifier(ChannelBuffer cb, byte protocolId)
77 throws BgpParseException {
mohamedrahil00f6f262016-11-24 20:20:41 +053078 log.debug("Parse local node descriptor");
Priyanka Bb2988fa2015-10-09 12:45:36 +053079 NodeDescriptors localNodeDescriptors = new NodeDescriptors();
80 localNodeDescriptors = parseLocalNodeDescriptors(cb, protocolId);
81
mohamedrahil00f6f262016-11-24 20:20:41 +053082 log.debug("MultiTopologyId TLV cannot repeat more than once");
Priyanka B02040732015-11-29 11:30:29 +053083 List<BgpValueType> prefixDescriptor = new LinkedList<>();
Priyanka Bb2988fa2015-10-09 12:45:36 +053084 prefixDescriptor = parsePrefixDescriptors(cb);
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053085 return new BgpPrefixLSIdentifier(localNodeDescriptors, prefixDescriptor);
Priyanka Bb2988fa2015-10-09 12:45:36 +053086 }
87
88 /**
89 * Parse local node descriptors.
90 *
91 * @param cb ChannelBuffer
92 * @param protocolId protocol identifier
93 * @return LocalNodeDescriptors
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053094 * @throws BgpParseException while parsing local node descriptors
Priyanka Bb2988fa2015-10-09 12:45:36 +053095 */
96 public static NodeDescriptors parseLocalNodeDescriptors(ChannelBuffer cb, byte protocolId)
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053097 throws BgpParseException {
Priyanka B02040732015-11-29 11:30:29 +053098 ChannelBuffer tempBuf = cb.copy();
Priyanka Bb2988fa2015-10-09 12:45:36 +053099 short type = cb.readShort();
100 short length = cb.readShort();
101 if (cb.readableBytes() < length) {
102 //length + 4 implies data contains type, length and value
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530103 throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.OPTIONAL_ATTRIBUTE_ERROR,
Priyanka Bb2988fa2015-10-09 12:45:36 +0530104 tempBuf.readBytes(cb.readableBytes() + TYPE_AND_LEN));
105 }
106 NodeDescriptors localNodeDescriptors = new NodeDescriptors();
107 ChannelBuffer tempCb = cb.readBytes(length);
108
109 if (type == NodeDescriptors.LOCAL_NODE_DES_TYPE) {
110 localNodeDescriptors = NodeDescriptors.read(tempCb, length, type, protocolId);
111 } else {
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530112 throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR,
113 BgpErrorType.MALFORMED_ATTRIBUTE_LIST, null);
Priyanka Bb2988fa2015-10-09 12:45:36 +0530114 }
115 return localNodeDescriptors;
116 }
117
118 /**
119 * Parse list of prefix descriptors.
120 *
121 * @param cb ChannelBuffer
122 * @return list of prefix descriptors
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530123 * @throws BgpParseException while parsing list of prefix descriptors
Priyanka Bb2988fa2015-10-09 12:45:36 +0530124 */
Priyanka B02040732015-11-29 11:30:29 +0530125 public static List<BgpValueType> parsePrefixDescriptors(ChannelBuffer cb) throws BgpParseException {
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530126 LinkedList<BgpValueType> prefixDescriptor = new LinkedList<>();
127 BgpValueType tlv = null;
Priyanka Bb2988fa2015-10-09 12:45:36 +0530128 boolean isIpReachInfo = false;
129 ChannelBuffer tempCb;
130 int count = 0;
131
132 while (cb.readableBytes() > 0) {
Priyanka B02040732015-11-29 11:30:29 +0530133 ChannelBuffer tempBuf = cb.copy();
Priyanka Bb2988fa2015-10-09 12:45:36 +0530134 short type = cb.readShort();
135 short length = cb.readShort();
136 if (cb.readableBytes() < length) {
137 //length + 4 implies data contains type, length and value
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530138 throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.OPTIONAL_ATTRIBUTE_ERROR,
Priyanka Bb2988fa2015-10-09 12:45:36 +0530139 tempBuf.readBytes(cb.readableBytes() + TYPE_AND_LEN));
140 }
141 tempCb = cb.readBytes(length);
142 switch (type) {
Jonathan Hart51539b82015-10-29 09:53:04 -0700143 case OspfRouteTypeTlv.TYPE:
144 tlv = OspfRouteTypeTlv.read(tempCb);
Priyanka Bb2988fa2015-10-09 12:45:36 +0530145 break;
146 case IPReachabilityInformationTlv.TYPE:
147 tlv = IPReachabilityInformationTlv.read(tempCb, length);
148 isIpReachInfo = true;
149 break;
150 case BgpAttrNodeMultiTopologyId.ATTRNODE_MULTITOPOLOGY:
151 tlv = BgpAttrNodeMultiTopologyId.read(tempCb);
152 count = count + 1;
153 if (count > 1) {
154 //length + 4 implies data contains type, length and value
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530155 throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR,
156 BgpErrorType.OPTIONAL_ATTRIBUTE_ERROR, tempBuf.readBytes(length + TYPE_AND_LEN));
Priyanka Bb2988fa2015-10-09 12:45:36 +0530157 }
158 break;
159 default:
160 UnSupportedAttribute.skipBytes(tempCb, length);
161 }
162 prefixDescriptor.add(tlv);
163 }
164
165 if (!isIpReachInfo) {
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530166 throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.OPTIONAL_ATTRIBUTE_ERROR,
Priyanka Bb2988fa2015-10-09 12:45:36 +0530167 null);
168 }
169 return prefixDescriptor;
170 }
171
172 /**
173 * Returns local node descriptors.
174 *
175 * @return local node descriptors
176 */
177 public NodeDescriptors getLocalNodeDescriptors() {
178 return this.localNodeDescriptors;
179 }
180
181 /**
182 * Returns Prefix descriptors.
183 *
184 * @return Prefix descriptors
185 */
Priyanka B02040732015-11-29 11:30:29 +0530186 public List<BgpValueType> getPrefixdescriptor() {
Priyanka Bb2988fa2015-10-09 12:45:36 +0530187 return this.prefixDescriptor;
188 }
189
190 @Override
191 public int hashCode() {
192 return Objects.hash(prefixDescriptor.hashCode(), localNodeDescriptors);
193 }
194
195 @Override
196 public boolean equals(Object obj) {
197 if (this == obj) {
198 return true;
199 }
200
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530201 if (obj instanceof BgpPrefixLSIdentifier) {
Priyanka Bb2988fa2015-10-09 12:45:36 +0530202 int countObjSubTlv = 0;
203 int countOtherSubTlv = 0;
204 boolean isCommonSubTlv = true;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530205 BgpPrefixLSIdentifier other = (BgpPrefixLSIdentifier) obj;
Priyanka Bb2988fa2015-10-09 12:45:36 +0530206
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530207 Iterator<BgpValueType> objListIterator = other.prefixDescriptor.iterator();
Priyanka Bb2988fa2015-10-09 12:45:36 +0530208 countOtherSubTlv = other.prefixDescriptor.size();
209 countObjSubTlv = prefixDescriptor.size();
210 if (countObjSubTlv != countOtherSubTlv) {
211 return false;
212 } else {
213 while (objListIterator.hasNext() && isCommonSubTlv) {
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530214 BgpValueType subTlv = objListIterator.next();
Priyanka B02040732015-11-29 11:30:29 +0530215 if (prefixDescriptor.contains(subTlv) && other.prefixDescriptor.contains(subTlv)) {
216 isCommonSubTlv = Objects.equals(prefixDescriptor.get(prefixDescriptor.indexOf(subTlv)),
217 other.prefixDescriptor.get(other.prefixDescriptor.indexOf(subTlv)));
218 } else {
219 isCommonSubTlv = false;
220 }
Priyanka Bb2988fa2015-10-09 12:45:36 +0530221 }
222 return isCommonSubTlv && Objects.equals(this.localNodeDescriptors, other.localNodeDescriptors);
223 }
224 }
225 return false;
226 }
227
228 @Override
229 public String toString() {
230 return MoreObjects.toStringHelper(getClass())
231 .add("localNodeDescriptors", localNodeDescriptors)
232 .add("prefixDescriptor", prefixDescriptor)
233 .toString();
234 }
Priyanka B02040732015-11-29 11:30:29 +0530235
236 @Override
237 public int compareTo(Object o) {
238 if (this.equals(o)) {
239 return 0;
240 }
241 int result = this.localNodeDescriptors.compareTo(((BgpPrefixLSIdentifier) o).localNodeDescriptors);
Priyanka Be2381842015-12-13 13:33:09 +0530242 boolean tlvFound = false;
Priyanka B02040732015-11-29 11:30:29 +0530243 if (result != 0) {
244 return result;
245 } else {
246 int countOtherSubTlv = ((BgpPrefixLSIdentifier) o).prefixDescriptor.size();
247 int countObjSubTlv = prefixDescriptor.size();
248 if (countOtherSubTlv != countObjSubTlv) {
249 if (countOtherSubTlv > countObjSubTlv) {
250 return 1;
251 } else {
252 return -1;
253 }
Priyanka Be2381842015-12-13 13:33:09 +0530254 }
Priyanka B02040732015-11-29 11:30:29 +0530255
256 ListIterator<BgpValueType> listIterator = prefixDescriptor.listIterator();
Priyanka B02040732015-11-29 11:30:29 +0530257 while (listIterator.hasNext()) {
Priyanka Be2381842015-12-13 13:33:09 +0530258 BgpValueType tlv1 = listIterator.next();
259 for (BgpValueType tlv : ((BgpPrefixLSIdentifier) o).prefixDescriptor) {
260 if (tlv.getType() == tlv1.getType()) {
261 result = prefixDescriptor.get(prefixDescriptor.indexOf(tlv1)).compareTo(
262 ((BgpPrefixLSIdentifier) o).prefixDescriptor
263 .get(((BgpPrefixLSIdentifier) o).prefixDescriptor.indexOf(tlv)));
264 if (result != 0) {
265 return result;
266 }
267 tlvFound = true;
268 break;
Priyanka B02040732015-11-29 11:30:29 +0530269 }
Priyanka Be2381842015-12-13 13:33:09 +0530270 }
271 if (!tlvFound) {
Shashikanth VHeacbed52015-12-02 22:37:21 +0530272 return 1;
Priyanka B02040732015-11-29 11:30:29 +0530273 }
274 }
275 }
276 return 0;
277 }
Jonathan Hart317f4762015-11-09 16:05:36 -0800278}