blob: 7bc4fcb3b2390394f56c6430a4a5b214b315d0fa [file] [log] [blame]
Priyanka Bb2988fa2015-10-09 12:45:36 +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 */
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;
Priyanka Bb2988fa2015-10-09 12:45:36 +053027import org.onosproject.bgpio.types.AreaIDTlv;
28import org.onosproject.bgpio.types.AutonomousSystemTlv;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053029import org.onosproject.bgpio.types.BgpErrorType;
30import org.onosproject.bgpio.types.BgpLSIdentifierTlv;
31import org.onosproject.bgpio.types.BgpValueType;
Priyanka Bb2988fa2015-10-09 12:45:36 +053032import org.onosproject.bgpio.types.IsIsNonPseudonode;
33import org.onosproject.bgpio.types.IsIsPseudonode;
34import org.onosproject.bgpio.types.OSPFNonPseudonode;
35import org.onosproject.bgpio.types.OSPFPseudonode;
36import org.onosproject.bgpio.util.UnSupportedAttribute;
37import org.slf4j.Logger;
38import org.slf4j.LoggerFactory;
39
40import com.google.common.base.MoreObjects;
41
42/**
43 * Provides Local and Remote NodeDescriptors which contains Node Descriptor Sub-TLVs.
44 */
45public class NodeDescriptors {
46
47 /*
48 *Reference :draft-ietf-idr-ls-distribution-11
49 0 1 2 3
50 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
51 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
52 | Type | Length |
53 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
54 | |
55 // Node Descriptor Sub-TLVs (variable) //
56 | |
57 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
58
59 Figure : Local or Remote Node Descriptors TLV format
60 */
61
Priyanka B02040732015-11-29 11:30:29 +053062 private static final Logger log = LoggerFactory.getLogger(NodeDescriptors.class);
Priyanka Bb2988fa2015-10-09 12:45:36 +053063
64 public static final short LOCAL_NODE_DES_TYPE = 256;
65 public static final short REMOTE_NODE_DES_TYPE = 257;
66 public static final short IGP_ROUTERID_TYPE = 515;
67 public static final short IS_IS_LEVEL_1_PROTOCOL_ID = 1;
68 public static final short IS_IS_LEVEL_2_PROTOCOL_ID = 2;
69 public static final short OSPF_V2_PROTOCOL_ID = 3;
70 public static final short OSPF_V3_PROTOCOL_ID = 6;
71 public static final int TYPE_AND_LEN = 4;
72 public static final int ISISNONPSEUDONODE_LEN = 6;
73 public static final int ISISPSEUDONODE_LEN = 7;
74 public static final int OSPFNONPSEUDONODE_LEN = 4;
75 public static final int OSPFPSEUDONODE_LEN = 8;
Priyanka B02040732015-11-29 11:30:29 +053076 private List<BgpValueType> subTlvs;
Priyanka Bb2988fa2015-10-09 12:45:36 +053077 private short deslength;
78 private short desType;
79
80 /**
81 * Resets parameters.
82 */
83 public NodeDescriptors() {
84 this.subTlvs = null;
85 this.deslength = 0;
86 this.desType = 0;
87 }
88
89 /**
90 * Constructor to initialize parameters.
91 *
92 * @param subTlvs list of subTlvs
93 * @param deslength Descriptors length
94 * @param desType local node descriptor or remote node descriptor type
95 */
Priyanka B02040732015-11-29 11:30:29 +053096 public NodeDescriptors(List<BgpValueType> subTlvs, short deslength, short desType) {
Priyanka Bb2988fa2015-10-09 12:45:36 +053097 this.subTlvs = subTlvs;
98 this.deslength = deslength;
99 this.desType = desType;
100 }
101
102 /**
103 * Returns list of subTlvs.
104 *
105 * @return subTlvs list of subTlvs
106 */
Priyanka B02040732015-11-29 11:30:29 +0530107 public List<BgpValueType> getSubTlvs() {
Priyanka Bb2988fa2015-10-09 12:45:36 +0530108 return subTlvs;
109 }
110
111 @Override
112 public int hashCode() {
113 return Objects.hash(subTlvs.hashCode());
114 }
115
116 @Override
117 public boolean equals(Object obj) {
118 if (this == obj) {
119 return true;
120 }
121
122 if (obj instanceof NodeDescriptors) {
123 int countObjSubTlv = 0;
124 int countOtherSubTlv = 0;
125 boolean isCommonSubTlv = true;
126 NodeDescriptors other = (NodeDescriptors) obj;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530127 Iterator<BgpValueType> objListIterator = other.subTlvs.iterator();
Priyanka Bb2988fa2015-10-09 12:45:36 +0530128 countOtherSubTlv = other.subTlvs.size();
129 countObjSubTlv = subTlvs.size();
130 if (countObjSubTlv != countOtherSubTlv) {
131 return false;
132 } else {
133 while (objListIterator.hasNext() && isCommonSubTlv) {
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530134 BgpValueType subTlv = objListIterator.next();
Priyanka B02040732015-11-29 11:30:29 +0530135 if (subTlvs.contains(subTlv) && other.subTlvs.contains(subTlv)) {
136 isCommonSubTlv = Objects.equals(subTlvs.get(subTlvs.indexOf(subTlv)),
137 other.subTlvs.get(other.subTlvs.indexOf(subTlv)));
138 } else {
139 isCommonSubTlv = false;
140 }
Priyanka Bb2988fa2015-10-09 12:45:36 +0530141 }
142 return isCommonSubTlv;
143 }
144 }
145 return false;
146 }
147
148 /**
149 * Reads node descriptors Sub-TLVs.
150 *
151 * @param cb ChannelBuffer
152 * @param desLength node descriptor length
153 * @param desType local node descriptor or remote node descriptor type
154 * @param protocolId protocol ID
155 * @return object of NodeDescriptors
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530156 * @throws BgpParseException while parsing node descriptors
Priyanka Bb2988fa2015-10-09 12:45:36 +0530157 */
158 public static NodeDescriptors read(ChannelBuffer cb, short desLength, short desType, byte protocolId)
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530159 throws BgpParseException {
Priyanka B02040732015-11-29 11:30:29 +0530160 log.debug("Read NodeDescriptor");
161 List<BgpValueType> subTlvs = new LinkedList<>();
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530162 BgpValueType tlv = null;
Priyanka Bb2988fa2015-10-09 12:45:36 +0530163
164 while (cb.readableBytes() > 0) {
Priyanka B02040732015-11-29 11:30:29 +0530165 ChannelBuffer tempBuf = cb.copy();
Priyanka Bb2988fa2015-10-09 12:45:36 +0530166 short type = cb.readShort();
167 short length = cb.readShort();
168 if (cb.readableBytes() < length) {
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530169 throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.OPTIONAL_ATTRIBUTE_ERROR,
Priyanka Bb2988fa2015-10-09 12:45:36 +0530170 tempBuf.readBytes(cb.readableBytes() + TYPE_AND_LEN));
171 }
172 ChannelBuffer tempCb = cb.readBytes(length);
173 switch (type) {
174 case AutonomousSystemTlv.TYPE:
175 tlv = AutonomousSystemTlv.read(tempCb);
176 break;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530177 case BgpLSIdentifierTlv.TYPE:
178 tlv = BgpLSIdentifierTlv.read(tempCb);
Priyanka Bb2988fa2015-10-09 12:45:36 +0530179 break;
180 case AreaIDTlv.TYPE:
181 tlv = AreaIDTlv.read(tempCb);
182 break;
183 case IGP_ROUTERID_TYPE:
184 if (protocolId == IS_IS_LEVEL_1_PROTOCOL_ID || protocolId == IS_IS_LEVEL_2_PROTOCOL_ID) {
Shashikanth VH795c89d2015-12-10 21:52:46 +0530185 boolean isNonPseudoNode = true;
186 if ((length == ISISPSEUDONODE_LEN) && (tempCb.getByte(ISISPSEUDONODE_LEN - 1) != 0)) {
187 isNonPseudoNode = false;
188 }
189 if (isNonPseudoNode) {
Priyanka Bb2988fa2015-10-09 12:45:36 +0530190 tlv = IsIsNonPseudonode.read(tempCb);
Shashikanth VH795c89d2015-12-10 21:52:46 +0530191 } else {
Priyanka Bb2988fa2015-10-09 12:45:36 +0530192 tlv = IsIsPseudonode.read(tempCb);
193 }
194 } else if (protocolId == OSPF_V2_PROTOCOL_ID || protocolId == OSPF_V3_PROTOCOL_ID) {
195 if (length == OSPFNONPSEUDONODE_LEN) {
196 tlv = OSPFNonPseudonode.read(tempCb);
197 } else if (length == OSPFPSEUDONODE_LEN) {
198 tlv = OSPFPseudonode.read(tempCb);
199 }
200 }
201 break;
202 default:
203 UnSupportedAttribute.skipBytes(tempCb, length);
204 }
205 subTlvs.add(tlv);
206 }
207 return new NodeDescriptors(subTlvs, desLength, desType);
208 }
209
210 /**
211 * Returns node descriptors length.
212 *
213 * @return node descriptors length
214 */
215 public short getLength() {
216 return this.deslength;
217 }
218
219 /**
220 * Returns node descriptors type.
221 *
222 * @return node descriptors type
223 */
224 public short getType() {
225 return this.desType;
226 }
227
228 @Override
229 public String toString() {
230 return MoreObjects.toStringHelper(getClass())
231 .add("desType", desType)
232 .add("deslength", deslength)
233 .add("subTlvs", subTlvs)
234 .toString();
235 }
Priyanka B02040732015-11-29 11:30:29 +0530236
Priyanka Be2381842015-12-13 13:33:09 +0530237 /**
238 * Compares this and o object.
239 *
240 * @param o object to be compared with this object
241 * @return which object is greater
242 */
Priyanka B02040732015-11-29 11:30:29 +0530243 public int compareTo(Object o) {
244 if (this.equals(o)) {
245 return 0;
246 }
247 ListIterator<BgpValueType> listIterator = subTlvs.listIterator();
Priyanka B02040732015-11-29 11:30:29 +0530248 int countOtherSubTlv = ((NodeDescriptors) o).subTlvs.size();
249 int countObjSubTlv = subTlvs.size();
Priyanka Be2381842015-12-13 13:33:09 +0530250 boolean tlvFound = false;
Priyanka B02040732015-11-29 11:30:29 +0530251 if (countOtherSubTlv != countObjSubTlv) {
Priyanka Be2381842015-12-13 13:33:09 +0530252 if (countOtherSubTlv > countObjSubTlv) {
253 return 1;
254 } else {
255 return -1;
256 }
Priyanka B02040732015-11-29 11:30:29 +0530257 } else {
258 while (listIterator.hasNext()) {
Priyanka Be2381842015-12-13 13:33:09 +0530259 BgpValueType tlv1 = listIterator.next();
Shashikanth VHeacbed52015-12-02 22:37:21 +0530260 log.debug("NodeDescriptor compare subtlv's");
Priyanka Be2381842015-12-13 13:33:09 +0530261 for (BgpValueType tlv : ((NodeDescriptors) o).subTlvs) {
262 if (tlv.getType() == tlv1.getType()) {
263 int result = subTlvs.get(subTlvs.indexOf(tlv1)).compareTo(
264 ((NodeDescriptors) o).subTlvs.get(((NodeDescriptors) o).subTlvs.indexOf(tlv)));
265 if (result != 0) {
266 return result;
267 }
268 tlvFound = true;
269 break;
Priyanka B02040732015-11-29 11:30:29 +0530270 }
Priyanka Be2381842015-12-13 13:33:09 +0530271 }
272 if (!tlvFound) {
Shashikanth VHeacbed52015-12-02 22:37:21 +0530273 return 1;
Priyanka B02040732015-11-29 11:30:29 +0530274 }
275 }
276 }
277 return 0;
278 }
Jonathan Hart317f4762015-11-09 16:05:36 -0800279}