blob: f6bd85cadafa55e9612f6dd61efe4275cb6444ea [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.
93 * Parameterized constructor which populate
94 *
95 * @param isisHeader isis header details
96 */
97 public LsPdu(IsisHeader isisHeader) {
98 populateHeader(isisHeader);
99 }
100
101 /**
102 * Adds the isis tlv to the list for the link state PDU.
103 *
104 * @param isisTlv isis tlv
105 */
106 public void addTlv(IsisTlv isisTlv) {
107 variableLengths.add(isisTlv);
108 }
109
110 /**
111 * Returns the remaining time of the link state pdu.
112 * Number of seconds before LSP considered expired
113 *
114 * @return remainingTime remaining time
115 */
116 public int remainingLifeTime() {
117 return remainingLifeTime;
118 }
119
120 /**
121 * Sets the remaining time for the link state pdu.
122 *
123 * @param remainingLifeTime remaining time
124 */
125 public void setRemainingLifeTime(int remainingLifeTime) {
126 this.remainingLifeTime = remainingLifeTime;
127 }
128
129 /**
130 * Returns the link state database overload.
131 *
132 * @return lspdbol link state database overload
133 */
134 public boolean lspDbol() {
135 return lspDbol;
136 }
137
138 /**
139 * Sets the link state database overload for this pdu.
140 *
141 * @param lspDbol link state database overload
142 */
143 public void setLspDbol(boolean lspDbol) {
144 this.lspDbol = lspDbol;
145 }
146
147 /**
148 * Returns the type block.
149 *
150 * @return type block
151 */
152 public byte typeBlock() {
153 return typeBlock;
154 }
155
156 /**
157 * Sets the type block.
158 *
159 * @param typeBlock type block
160 */
161 public void setTypeBlock(byte typeBlock) {
162 this.typeBlock = typeBlock;
163 }
164
165 /**
166 * Returns the sequence number of LSP.
167 *
168 * @return sequenceNumber sequence number
169 */
170 public int sequenceNumber() {
171 return sequenceNumber;
172 }
173
174 /**
175 * Sets the sequence nubmer for LSP.
176 *
177 * @param sequenceNumber sequence number
178 */
179 public void setSequenceNumber(int sequenceNumber) {
180 this.sequenceNumber = sequenceNumber;
181 }
182
183 /**
184 * Returns the checksum of LSP from Source ID to end.
185 *
186 * @return checkSum check sum
187 */
188 public int checkSum() {
189 return checkSum;
190 }
191
192 /**
193 * Sets the checksum for LSP from Source ID to end.
194 *
195 * @param checkSum check sum
196 */
197 public void setCheckSum(int checkSum) {
198 this.checkSum = checkSum;
199 }
200
201 /**
202 * Returns the partition repair value of the intermediate system.
203 *
204 * @return partitionRepair partition repair
205 */
206 public boolean partitionRepair() {
207 return partitionRepair;
208 }
209
210 /**
211 * Sets partition repair value for the intermediate system.
212 *
213 * @param partitionRepair partition repair
214 */
215 public void setPartitionRepair(boolean partitionRepair) {
216 this.partitionRepair = partitionRepair;
217 }
218
219 /**
220 * Returns the value of intermediate system attached field.
221 * return values based on type Default Metric, Delay Metric, Expense Metric, Error Metric
222 *
223 * @return attachedToOtherAreas attached to other areas
224 */
225 public AttachedToOtherAreas attachedToOtherAreas() {
226 return attachedToOtherAreas;
227 }
228
229 /**
230 * Sets the value for intermediate system attached field.
231 * it will pass values based on type Default Metric, Delay Metric, Expense Metric, Error Metric
232 *
233 * @param attachedToOtherAreas attached to other areas
234 */
235 public void setAttachedToOtherAreas(AttachedToOtherAreas attachedToOtherAreas) {
236 this.attachedToOtherAreas = attachedToOtherAreas;
237 }
238
239 /**
240 * Returns the intermediate system type.
241 * type will be level 1 or level 2
242 *
243 * @return intermediateSystemType intermediate system type
244 */
245 public byte intermediateSystemType() {
246 return intermediateSystemType;
247 }
248
249 /**
250 * Sets the value for intermediate system.
251 * type will be level 1 or level 2
252 *
253 * @param intermediateSystemType intermediate system type
254 */
255 public void setIntermediateSystemType(byte intermediateSystemType) {
256 this.intermediateSystemType = intermediateSystemType;
257 }
258
259 /**
260 * Returns the link state ID of link state packet.
261 * System ID of the source of link state PDU
262 *
263 * @return lspId link state packet ID
264 */
265 public String lspId() {
266 return lspId;
267 }
268
269 /**
270 * Sets the link state ID for link state packet.
271 * System ID of the source of link state PDU
272 *
273 * @param lspId link state packet ID
274 */
275 public void setLspId(String lspId) {
276 this.lspId = lspId;
277 }
278
279 /**
280 * Returns the packet data unit length of link state packet.
281 * Entire length of this PDU, in octets
282 *
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530283 * @return pduLength packet data unit length
Dhruv Dhodye64b93e2016-04-20 19:26:55 +0530284 */
285 public int pduLength() {
286 return pduLength;
287 }
288
289 /**
290 * Sets the packet data unit length for link state packet.
291 * Entire Length of this PDU, in octets
292 *
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530293 * @param pduLength packet data length
Dhruv Dhodye64b93e2016-04-20 19:26:55 +0530294 */
295 public void setPduLength(int pduLength) {
296 this.pduLength = pduLength;
297 }
298
299 @Override
300 public void readFrom(ChannelBuffer channelBuffer) {
301
302 this.setPduLength(channelBuffer.readUnsignedShort());
303 this.setRemainingLifeTime(channelBuffer.readUnsignedShort());
304 //lsp id + 2 value
305 byte[] tempByteArray = new byte[IsisUtil.ID_PLUS_TWO_BYTE];
306 channelBuffer.readBytes(tempByteArray, 0, IsisUtil.ID_PLUS_TWO_BYTE);
307 this.setLspId(IsisUtil.systemIdPlus(tempByteArray));
308 //sequence number 4
309 this.setSequenceNumber(channelBuffer.readInt());
310 this.setCheckSum(channelBuffer.readUnsignedShort());
311 int typeTemp = channelBuffer.readUnsignedByte();
312 byte isTypeByte = (byte) typeTemp;
313 String tempValue = String.format("%8s", Integer.toBinaryString(isTypeByte & 0xFF)).replace(' ', '0');
314 int pBit = Integer.parseInt(new Character(tempValue.charAt(0)).toString());
315 if (pBit == 1) {
316 this.setPartitionRepair(true);
317 } else {
318 this.setPartitionRepair(false);
319 }
320 int attValue = Integer.parseInt(tempValue.substring(1, 5), 2);
321 switch (AttachedToOtherAreas.get(attValue)) {
322 case DEFAULTMETRIC:
323 this.setAttachedToOtherAreas(AttachedToOtherAreas.DEFAULTMETRIC);
324 break;
325 case DELAYMETRIC:
326 this.setAttachedToOtherAreas(AttachedToOtherAreas.DELAYMETRIC);
327 break;
328 case EXPENSEMETRIC:
329 this.setAttachedToOtherAreas(AttachedToOtherAreas.EXPENSEMETRIC);
330 break;
331 case ERRORMETRIC:
332 this.setAttachedToOtherAreas(AttachedToOtherAreas.ERRORMETRIC);
333 break;
334 case NONE:
335 this.setAttachedToOtherAreas(AttachedToOtherAreas.NONE);
336 break;
337 default:
338 break;
339 }
340 int lspdbol = Integer.parseInt(new Character(tempValue.charAt(5)).toString());
341 if (lspdbol == 1) {
342 this.setLspDbol(true);
343 } else {
344 this.setLspDbol(false);
345 }
346 int isType = Integer.parseInt(tempValue.substring(6, 8), 2);
347 byte isTypeByteValue = (byte) isType;
348 this.setIntermediateSystemType(isTypeByteValue);
349 //tlv here
350 while (channelBuffer.readableBytes() > 0) {
351 TlvHeader tlvHeader = new TlvHeader();
352 tlvHeader.setTlvType(channelBuffer.readUnsignedByte());
353 tlvHeader.setTlvLength(channelBuffer.readUnsignedByte());
354 TlvType tlvValue = TlvType.get(tlvHeader.tlvType());
355 if (tlvValue != null) {
356 IsisTlv tlv = TlvFinder.findTlv(tlvHeader, channelBuffer.readBytes(tlvHeader.tlvLength()));
357 this.variableLengths.add(tlv);
358 } else {
359 channelBuffer.readBytes(tlvHeader.tlvLength());
360 }
361 }
362 }
363
364 @Override
365 public byte[] asBytes() {
366 byte[] lspMessage = null;
367 byte[] helloHeader = l1l2IsisPduHeader();
368 byte[] lspBody = l1l2LsPduBody();
369 lspMessage = Bytes.concat(helloHeader, lspBody);
370 return lspMessage;
371 }
372
373 /**
374 * Builds ISIS PDU header from ISIS message.
375 *
376 * @return headerList ISIS PDU header
377 */
378 public byte[] l1l2IsisPduHeader() {
379 List<Byte> headerList = new ArrayList<>();
380 headerList.add(this.irpDiscriminator());
381 headerList.add((byte) IsisUtil.getPduHeaderLength(this.pduType()));
382 headerList.add(this.version());
383 headerList.add(this.idLength());
384 headerList.add((byte) this.pduType());
385 headerList.add(this.version2());
386 headerList.add(this.reserved());
387 headerList.add(this.maximumAreaAddresses());
388 return Bytes.toArray(headerList);
389 }
390
391 /**
392 * Builds link state PDU body from ISIS message.
393 *
394 * @return bodyList link state PDU body
395 */
396 public byte[] l1l2LsPduBody() {
397 List<Byte> bodyList = new ArrayList<>();
398 bodyList.addAll(Bytes.asList(IsisUtil.convertToTwoBytes(this.pduLength())));
399 bodyList.addAll(Bytes.asList(IsisUtil.convertToTwoBytes(this.remainingLifeTime())));
400 bodyList.addAll(IsisUtil.sourceAndLanIdToBytes(this.lspId()));
401 bodyList.addAll(Bytes.asList(IsisUtil.convertToFourBytes(this.sequenceNumber())));
402 bodyList.addAll(Bytes.asList(IsisUtil.convertToTwoBytes(this.checkSum())));
403 String temString = "";
404 if (this.partitionRepair()) {
405 temString = "1" + temString;
406 } else {
407 temString = "0" + temString;
408 }
409 switch (this.attachedToOtherAreas()) {
410 case ERRORMETRIC:
411 temString = temString + "1000";
412 break;
413 case EXPENSEMETRIC:
414 temString = temString + "0100";
415 break;
416 case DELAYMETRIC:
417 temString = temString + "0010";
418 break;
419 case DEFAULTMETRIC:
420 temString = temString + "0001";
421 break;
422 case NONE:
423 temString = temString + "0000";
424 break;
425 default:
426 break;
427 }
428 if (this.lspDbol()) {
429 temString = temString + "1";
430 } else {
431 temString = temString + "0";
432 }
433 String isType = Integer.toBinaryString(this.intermediateSystemType());
434 if (isType.length() % 2 != 0) {
435 isType = "0" + isType;
436 }
437 temString = temString + isType;
438 bodyList.add((byte) Integer.parseInt(temString, 2));
439 for (IsisTlv isisTlv : variableLengths) {
440 bodyList.addAll(TlvsToBytes.tlvToBytes(isisTlv));
441 }
442 return Bytes.toArray(bodyList);
443 }
444
445 @Override
446 public String toString() {
447 return MoreObjects.toStringHelper(getClass())
448 .omitNullValues()
449 .add("pduLength", pduLength)
450 .add("remainingLifeTime", remainingLifeTime)
451 .add("lspId", lspId)
452 .add("sequenceNumber", sequenceNumber)
453 .add("checkSum", checkSum)
454 .add("partitionRepair", partitionRepair)
455 .add("lspDbol", lspDbol)
456 .add("typeBlock", typeBlock)
457 .add("intermediateSystemType", intermediateSystemType)
458 .toString();
459 }
460
461 @Override
462 public boolean equals(Object o) {
463 if (this == o) {
464 return true;
465 }
466 if (o == null || getClass() != o.getClass()) {
467 return false;
468 }
469 LsPdu that = (LsPdu) o;
470 return Objects.equal(pduLength, that.pduLength) &&
471 Objects.equal(remainingLifeTime, that.remainingLifeTime) &&
472 Objects.equal(lspId, that.lspId) &&
473 Objects.equal(sequenceNumber, that.sequenceNumber) &&
474 Objects.equal(checkSum, that.checkSum) &&
475 Objects.equal(partitionRepair, that.partitionRepair) &&
476 Objects.equal(lspDbol, that.lspDbol) &&
477 Objects.equal(typeBlock, that.typeBlock) &&
478 Objects.equal(intermediateSystemType, that.intermediateSystemType);
479 }
480
481 @Override
482 public int hashCode() {
483 return Objects.hashCode(pduLength, remainingLifeTime, lspId, sequenceNumber,
484 checkSum, partitionRepair, lspDbol, typeBlock, intermediateSystemType);
485 }
486}