blob: 971f9a13ccf4b46132f735472d783d7c67a56d5a [file] [log] [blame]
Dhruv Dhodye64b93e2016-04-20 19:26:55 +05301/*
2 * Copyright 2016-present 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
17package org.onosproject.isis.io.isispacket.pdu;
18
19import com.google.common.base.MoreObjects;
20import com.google.common.base.Objects;
21import com.google.common.primitives.Bytes;
22import org.jboss.netty.buffer.ChannelBuffer;
23import org.onosproject.isis.io.isispacket.IsisHeader;
24import org.onosproject.isis.io.isispacket.tlv.IsisTlv;
25import org.onosproject.isis.io.isispacket.tlv.TlvFinder;
26import org.onosproject.isis.io.isispacket.tlv.TlvHeader;
27import org.onosproject.isis.io.isispacket.tlv.TlvType;
28import org.onosproject.isis.io.isispacket.tlv.TlvsToBytes;
29import org.onosproject.isis.io.util.IsisUtil;
30
31import java.util.ArrayList;
32import java.util.List;
33
34/**
35 * Representation of an ISIS Link State packet.
36 * Each Link State packet carries a collection of TLVs
37 * Several TLVs may be included in a single packet.
38 */
39public class LsPdu extends IsisHeader {
40
41 /*
42 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
43 | Intra-domain Routing Protocol Discriminator |
44 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
45 | Length Indicator |
46 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
47 | Version/Protocol ID Extension |
48 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
49 | ID Length |
50 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
51 | R | R | R | PDU Type |
52 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
53 | Version |
54 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
55 | Reserved |
56 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
57 | Maximum area address |
58 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59 | PDU Length |
60 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
61 | Remaining Lifetime |
62 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
63 | LSP ID |
64 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
65 | PDU Length |
66 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
67 | Sequence Number |
68 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
69 | Checksum |
70 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
71 | P | ATT | LSPDBOL | IS Type |
72 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
73 | Variable Lengths Fields |
74 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
75
76 LS PDU Format
77 REFERENCE : ISO/IECĀ 10589
78 */
79 private int pduLength;
80 private int remainingLifeTime;
81 private String lspId;
82 private int sequenceNumber;
83 private int checkSum;
84 private boolean partitionRepair;
85 private AttachedToOtherAreas attachedToOtherAreas;
86 private boolean lspDbol;
87 private byte typeBlock;
88 private byte intermediateSystemType;
89 private List<IsisTlv> variableLengths = new ArrayList<>();
90
91 /**
92 * Creates an instance of Link State packet.
Dhruv Dhodye64b93e2016-04-20 19:26:55 +053093 *
94 * @param isisHeader isis header details
95 */
96 public LsPdu(IsisHeader isisHeader) {
97 populateHeader(isisHeader);
98 }
99
100 /**
sunish vk7bdf4d42016-06-24 12:29:43 +0530101 * Returns the ISIS tlvs.
102 *
103 * @return tlvs
104 */
105 public List<IsisTlv> tlvs() {
106 return this.variableLengths;
107 }
108
109 /**
Dhruv Dhodye64b93e2016-04-20 19:26:55 +0530110 * Adds the isis tlv to the list for the link state PDU.
111 *
112 * @param isisTlv isis tlv
113 */
114 public void addTlv(IsisTlv isisTlv) {
115 variableLengths.add(isisTlv);
116 }
117
118 /**
119 * Returns the remaining time of the link state pdu.
120 * Number of seconds before LSP considered expired
121 *
122 * @return remainingTime remaining time
123 */
124 public int remainingLifeTime() {
125 return remainingLifeTime;
126 }
127
128 /**
129 * Sets the remaining time for the link state pdu.
130 *
131 * @param remainingLifeTime remaining time
132 */
133 public void setRemainingLifeTime(int remainingLifeTime) {
134 this.remainingLifeTime = remainingLifeTime;
135 }
136
137 /**
138 * Returns the link state database overload.
139 *
140 * @return lspdbol link state database overload
141 */
142 public boolean lspDbol() {
143 return lspDbol;
144 }
145
146 /**
147 * Sets the link state database overload for this pdu.
148 *
149 * @param lspDbol link state database overload
150 */
151 public void setLspDbol(boolean lspDbol) {
152 this.lspDbol = lspDbol;
153 }
154
155 /**
156 * Returns the type block.
157 *
158 * @return type block
159 */
160 public byte typeBlock() {
161 return typeBlock;
162 }
163
164 /**
165 * Sets the type block.
166 *
167 * @param typeBlock type block
168 */
169 public void setTypeBlock(byte typeBlock) {
170 this.typeBlock = typeBlock;
171 }
172
173 /**
174 * Returns the sequence number of LSP.
175 *
176 * @return sequenceNumber sequence number
177 */
178 public int sequenceNumber() {
179 return sequenceNumber;
180 }
181
182 /**
183 * Sets the sequence nubmer for LSP.
184 *
185 * @param sequenceNumber sequence number
186 */
187 public void setSequenceNumber(int sequenceNumber) {
188 this.sequenceNumber = sequenceNumber;
189 }
190
191 /**
192 * Returns the checksum of LSP from Source ID to end.
193 *
194 * @return checkSum check sum
195 */
196 public int checkSum() {
197 return checkSum;
198 }
199
200 /**
201 * Sets the checksum for LSP from Source ID to end.
202 *
203 * @param checkSum check sum
204 */
205 public void setCheckSum(int checkSum) {
206 this.checkSum = checkSum;
207 }
208
209 /**
210 * Returns the partition repair value of the intermediate system.
211 *
212 * @return partitionRepair partition repair
213 */
214 public boolean partitionRepair() {
215 return partitionRepair;
216 }
217
218 /**
219 * Sets partition repair value for the intermediate system.
220 *
221 * @param partitionRepair partition repair
222 */
223 public void setPartitionRepair(boolean partitionRepair) {
224 this.partitionRepair = partitionRepair;
225 }
226
227 /**
228 * Returns the value of intermediate system attached field.
229 * return values based on type Default Metric, Delay Metric, Expense Metric, Error Metric
230 *
231 * @return attachedToOtherAreas attached to other areas
232 */
233 public AttachedToOtherAreas attachedToOtherAreas() {
234 return attachedToOtherAreas;
235 }
236
237 /**
238 * Sets the value for intermediate system attached field.
239 * it will pass values based on type Default Metric, Delay Metric, Expense Metric, Error Metric
240 *
241 * @param attachedToOtherAreas attached to other areas
242 */
243 public void setAttachedToOtherAreas(AttachedToOtherAreas attachedToOtherAreas) {
244 this.attachedToOtherAreas = attachedToOtherAreas;
245 }
246
247 /**
248 * Returns the intermediate system type.
249 * type will be level 1 or level 2
250 *
251 * @return intermediateSystemType intermediate system type
252 */
253 public byte intermediateSystemType() {
254 return intermediateSystemType;
255 }
256
257 /**
258 * Sets the value for intermediate system.
259 * type will be level 1 or level 2
260 *
261 * @param intermediateSystemType intermediate system type
262 */
263 public void setIntermediateSystemType(byte intermediateSystemType) {
264 this.intermediateSystemType = intermediateSystemType;
265 }
266
267 /**
268 * Returns the link state ID of link state packet.
269 * System ID of the source of link state PDU
270 *
271 * @return lspId link state packet ID
272 */
273 public String lspId() {
274 return lspId;
275 }
276
277 /**
278 * Sets the link state ID for link state packet.
279 * System ID of the source of link state PDU
280 *
281 * @param lspId link state packet ID
282 */
283 public void setLspId(String lspId) {
284 this.lspId = lspId;
285 }
286
287 /**
288 * Returns the packet data unit length of link state packet.
289 * Entire length of this PDU, in octets
290 *
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530291 * @return pduLength packet data unit length
Dhruv Dhodye64b93e2016-04-20 19:26:55 +0530292 */
293 public int pduLength() {
294 return pduLength;
295 }
296
297 /**
298 * Sets the packet data unit length for link state packet.
299 * Entire Length of this PDU, in octets
300 *
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530301 * @param pduLength packet data length
Dhruv Dhodye64b93e2016-04-20 19:26:55 +0530302 */
303 public void setPduLength(int pduLength) {
304 this.pduLength = pduLength;
305 }
306
307 @Override
308 public void readFrom(ChannelBuffer channelBuffer) {
309
310 this.setPduLength(channelBuffer.readUnsignedShort());
311 this.setRemainingLifeTime(channelBuffer.readUnsignedShort());
312 //lsp id + 2 value
313 byte[] tempByteArray = new byte[IsisUtil.ID_PLUS_TWO_BYTE];
314 channelBuffer.readBytes(tempByteArray, 0, IsisUtil.ID_PLUS_TWO_BYTE);
315 this.setLspId(IsisUtil.systemIdPlus(tempByteArray));
316 //sequence number 4
317 this.setSequenceNumber(channelBuffer.readInt());
318 this.setCheckSum(channelBuffer.readUnsignedShort());
319 int typeTemp = channelBuffer.readUnsignedByte();
320 byte isTypeByte = (byte) typeTemp;
321 String tempValue = String.format("%8s", Integer.toBinaryString(isTypeByte & 0xFF)).replace(' ', '0');
322 int pBit = Integer.parseInt(new Character(tempValue.charAt(0)).toString());
323 if (pBit == 1) {
324 this.setPartitionRepair(true);
325 } else {
326 this.setPartitionRepair(false);
327 }
328 int attValue = Integer.parseInt(tempValue.substring(1, 5), 2);
329 switch (AttachedToOtherAreas.get(attValue)) {
330 case DEFAULTMETRIC:
331 this.setAttachedToOtherAreas(AttachedToOtherAreas.DEFAULTMETRIC);
332 break;
333 case DELAYMETRIC:
334 this.setAttachedToOtherAreas(AttachedToOtherAreas.DELAYMETRIC);
335 break;
336 case EXPENSEMETRIC:
337 this.setAttachedToOtherAreas(AttachedToOtherAreas.EXPENSEMETRIC);
338 break;
339 case ERRORMETRIC:
340 this.setAttachedToOtherAreas(AttachedToOtherAreas.ERRORMETRIC);
341 break;
342 case NONE:
343 this.setAttachedToOtherAreas(AttachedToOtherAreas.NONE);
344 break;
345 default:
346 break;
347 }
348 int lspdbol = Integer.parseInt(new Character(tempValue.charAt(5)).toString());
349 if (lspdbol == 1) {
350 this.setLspDbol(true);
351 } else {
352 this.setLspDbol(false);
353 }
354 int isType = Integer.parseInt(tempValue.substring(6, 8), 2);
355 byte isTypeByteValue = (byte) isType;
356 this.setIntermediateSystemType(isTypeByteValue);
357 //tlv here
358 while (channelBuffer.readableBytes() > 0) {
359 TlvHeader tlvHeader = new TlvHeader();
360 tlvHeader.setTlvType(channelBuffer.readUnsignedByte());
361 tlvHeader.setTlvLength(channelBuffer.readUnsignedByte());
362 TlvType tlvValue = TlvType.get(tlvHeader.tlvType());
363 if (tlvValue != null) {
364 IsisTlv tlv = TlvFinder.findTlv(tlvHeader, channelBuffer.readBytes(tlvHeader.tlvLength()));
sunish vkc3824e82016-05-11 19:38:24 +0530365 if (tlv != null) {
366 this.variableLengths.add(tlv);
367 }
Dhruv Dhodye64b93e2016-04-20 19:26:55 +0530368 } else {
369 channelBuffer.readBytes(tlvHeader.tlvLength());
370 }
371 }
372 }
373
374 @Override
375 public byte[] asBytes() {
376 byte[] lspMessage = null;
377 byte[] helloHeader = l1l2IsisPduHeader();
378 byte[] lspBody = l1l2LsPduBody();
379 lspMessage = Bytes.concat(helloHeader, lspBody);
380 return lspMessage;
381 }
382
383 /**
384 * Builds ISIS PDU header from ISIS message.
385 *
386 * @return headerList ISIS PDU header
387 */
388 public byte[] l1l2IsisPduHeader() {
389 List<Byte> headerList = new ArrayList<>();
390 headerList.add(this.irpDiscriminator());
391 headerList.add((byte) IsisUtil.getPduHeaderLength(this.pduType()));
392 headerList.add(this.version());
393 headerList.add(this.idLength());
394 headerList.add((byte) this.pduType());
395 headerList.add(this.version2());
396 headerList.add(this.reserved());
397 headerList.add(this.maximumAreaAddresses());
398 return Bytes.toArray(headerList);
399 }
400
401 /**
402 * Builds link state PDU body from ISIS message.
403 *
404 * @return bodyList link state PDU body
405 */
406 public byte[] l1l2LsPduBody() {
407 List<Byte> bodyList = new ArrayList<>();
408 bodyList.addAll(Bytes.asList(IsisUtil.convertToTwoBytes(this.pduLength())));
409 bodyList.addAll(Bytes.asList(IsisUtil.convertToTwoBytes(this.remainingLifeTime())));
410 bodyList.addAll(IsisUtil.sourceAndLanIdToBytes(this.lspId()));
411 bodyList.addAll(Bytes.asList(IsisUtil.convertToFourBytes(this.sequenceNumber())));
412 bodyList.addAll(Bytes.asList(IsisUtil.convertToTwoBytes(this.checkSum())));
413 String temString = "";
414 if (this.partitionRepair()) {
415 temString = "1" + temString;
416 } else {
417 temString = "0" + temString;
418 }
419 switch (this.attachedToOtherAreas()) {
420 case ERRORMETRIC:
421 temString = temString + "1000";
422 break;
423 case EXPENSEMETRIC:
424 temString = temString + "0100";
425 break;
426 case DELAYMETRIC:
427 temString = temString + "0010";
428 break;
429 case DEFAULTMETRIC:
430 temString = temString + "0001";
431 break;
432 case NONE:
433 temString = temString + "0000";
434 break;
435 default:
436 break;
437 }
438 if (this.lspDbol()) {
439 temString = temString + "1";
440 } else {
441 temString = temString + "0";
442 }
443 String isType = Integer.toBinaryString(this.intermediateSystemType());
444 if (isType.length() % 2 != 0) {
445 isType = "0" + isType;
446 }
447 temString = temString + isType;
448 bodyList.add((byte) Integer.parseInt(temString, 2));
449 for (IsisTlv isisTlv : variableLengths) {
450 bodyList.addAll(TlvsToBytes.tlvToBytes(isisTlv));
451 }
452 return Bytes.toArray(bodyList);
453 }
454
455 @Override
456 public String toString() {
457 return MoreObjects.toStringHelper(getClass())
458 .omitNullValues()
459 .add("pduLength", pduLength)
460 .add("remainingLifeTime", remainingLifeTime)
461 .add("lspId", lspId)
462 .add("sequenceNumber", sequenceNumber)
463 .add("checkSum", checkSum)
464 .add("partitionRepair", partitionRepair)
465 .add("lspDbol", lspDbol)
466 .add("typeBlock", typeBlock)
467 .add("intermediateSystemType", intermediateSystemType)
468 .toString();
469 }
470
471 @Override
472 public boolean equals(Object o) {
473 if (this == o) {
474 return true;
475 }
476 if (o == null || getClass() != o.getClass()) {
477 return false;
478 }
479 LsPdu that = (LsPdu) o;
480 return Objects.equal(pduLength, that.pduLength) &&
481 Objects.equal(remainingLifeTime, that.remainingLifeTime) &&
482 Objects.equal(lspId, that.lspId) &&
483 Objects.equal(sequenceNumber, that.sequenceNumber) &&
484 Objects.equal(checkSum, that.checkSum) &&
485 Objects.equal(partitionRepair, that.partitionRepair) &&
486 Objects.equal(lspDbol, that.lspDbol) &&
487 Objects.equal(typeBlock, that.typeBlock) &&
488 Objects.equal(intermediateSystemType, that.intermediateSystemType);
489 }
490
491 @Override
492 public int hashCode() {
493 return Objects.hashCode(pduLength, remainingLifeTime, lspId, sequenceNumber,
494 checkSum, partitionRepair, lspDbol, typeBlock, intermediateSystemType);
495 }
496}