blob: 7fb1b316b58a453d8990aeb84361dd460ea0fe66 [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) {
185 if (length == ISISNONPSEUDONODE_LEN) {
186 tlv = IsIsNonPseudonode.read(tempCb);
187 } else if (length == ISISPSEUDONODE_LEN) {
188 tlv = IsIsPseudonode.read(tempCb);
189 }
190 } else if (protocolId == OSPF_V2_PROTOCOL_ID || protocolId == OSPF_V3_PROTOCOL_ID) {
191 if (length == OSPFNONPSEUDONODE_LEN) {
192 tlv = OSPFNonPseudonode.read(tempCb);
193 } else if (length == OSPFPSEUDONODE_LEN) {
194 tlv = OSPFPseudonode.read(tempCb);
195 }
196 }
197 break;
198 default:
199 UnSupportedAttribute.skipBytes(tempCb, length);
200 }
201 subTlvs.add(tlv);
202 }
203 return new NodeDescriptors(subTlvs, desLength, desType);
204 }
205
206 /**
207 * Returns node descriptors length.
208 *
209 * @return node descriptors length
210 */
211 public short getLength() {
212 return this.deslength;
213 }
214
215 /**
216 * Returns node descriptors type.
217 *
218 * @return node descriptors type
219 */
220 public short getType() {
221 return this.desType;
222 }
223
224 @Override
225 public String toString() {
226 return MoreObjects.toStringHelper(getClass())
227 .add("desType", desType)
228 .add("deslength", deslength)
229 .add("subTlvs", subTlvs)
230 .toString();
231 }
Priyanka B02040732015-11-29 11:30:29 +0530232
233 public int compareTo(Object o) {
234 if (this.equals(o)) {
235 return 0;
236 }
237 ListIterator<BgpValueType> listIterator = subTlvs.listIterator();
238 ListIterator<BgpValueType> listIteratorOther = ((NodeDescriptors) o).subTlvs.listIterator();
239 int countOtherSubTlv = ((NodeDescriptors) o).subTlvs.size();
240 int countObjSubTlv = subTlvs.size();
241 if (countOtherSubTlv != countObjSubTlv) {
242 if (countOtherSubTlv > countObjSubTlv) {
243 return 1;
244 } else {
245 return -1;
246 }
247 } else {
248 while (listIterator.hasNext()) {
249 BgpValueType tlv = listIterator.next();
250 BgpValueType tlv1 = listIteratorOther.next();
251 if (subTlvs.contains(tlv) && ((NodeDescriptors) o).subTlvs.contains(tlv1)) {
252 int result = subTlvs.get(subTlvs.indexOf(tlv)).compareTo(
253 ((NodeDescriptors) o).subTlvs.get(((NodeDescriptors) o).subTlvs.indexOf(tlv1)));
254 if (result != 0) {
255 return result;
256 }
257 }
258 }
259 }
260 return 0;
261 }
Jonathan Hart317f4762015-11-09 16:05:36 -0800262}