blob: bbeb4ddd9cbc6da3bb673786b100f81beedf9f73 [file] [log] [blame]
tejeshwer degala3fe1ed52016-04-22 17:04:01 +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 */
16package org.onosproject.isis.controller.impl;
17
18import org.jboss.netty.channel.Channel;
19import org.onlab.packet.Ip4Address;
20import org.onlab.packet.MacAddress;
21import org.onosproject.isis.controller.IsisInterface;
22import org.onosproject.isis.controller.IsisInterfaceState;
23import org.onosproject.isis.controller.IsisLsdb;
24import org.onosproject.isis.controller.IsisMessage;
25import org.onosproject.isis.controller.IsisNeighbor;
26import org.onosproject.isis.controller.IsisNetworkType;
27import org.onosproject.isis.controller.IsisPduType;
28import org.onosproject.isis.controller.IsisRouterType;
29import org.onosproject.isis.controller.LspWrapper;
30import org.onosproject.isis.io.isispacket.IsisHeader;
31import org.onosproject.isis.io.isispacket.pdu.Csnp;
32import org.onosproject.isis.io.isispacket.pdu.HelloPdu;
33import org.onosproject.isis.io.isispacket.pdu.L1L2HelloPdu;
34import org.onosproject.isis.io.isispacket.pdu.LsPdu;
35import org.onosproject.isis.io.isispacket.pdu.P2PHelloPdu;
36import org.onosproject.isis.io.isispacket.pdu.Psnp;
37import org.onosproject.isis.io.isispacket.tlv.AdjacencyStateTlv;
38import org.onosproject.isis.io.isispacket.tlv.IsisTlv;
39import org.onosproject.isis.io.isispacket.tlv.LspEntriesTlv;
40import org.onosproject.isis.io.isispacket.tlv.LspEntry;
41import org.onosproject.isis.io.isispacket.tlv.TlvHeader;
42import org.onosproject.isis.io.isispacket.tlv.TlvType;
43import org.onosproject.isis.io.util.IsisConstants;
44import org.onosproject.isis.io.util.IsisUtil;
45import org.onosproject.isis.io.util.LspGenerator;
46import org.slf4j.Logger;
47import org.slf4j.LoggerFactory;
48
49import java.util.ArrayList;
50import java.util.Iterator;
51import java.util.List;
52import java.util.Map;
53import java.util.Set;
54import java.util.concurrent.ConcurrentHashMap;
55import java.util.concurrent.Executors;
56import java.util.concurrent.ScheduledExecutorService;
57import java.util.concurrent.ScheduledFuture;
58import java.util.concurrent.TimeUnit;
59
60/**
61 * Representation of an ISIS interface.
62 */
63public class DefaultIsisInterface implements IsisInterface {
64 private static final Logger log = LoggerFactory.getLogger(DefaultIsisInterface.class);
65 boolean flagValue = false;
66 private int interfaceIndex;
67 private Ip4Address interfaceIpAddress;
68 private byte[] networkMask;
69 private MacAddress interfaceMacAddress;
70 private String intermediateSystemName;
71 private String systemId;
72 private String l1LanId;
73 private String l2LanId;
74 private int idLength;
75 private int maxAreaAddresses;
76 private int reservedPacketCircuitType;
77 private IsisNetworkType networkType;
78 private String areaAddress;
79 private int areaLength;
80 private String lspId;
81 private int holdingTime;
82 private int priority;
83 private String circuitId;
84 private int helloInterval;
85 private Map<MacAddress, IsisNeighbor> neighborList = new ConcurrentHashMap<>();
86 private IsisHelloPduSender isisHelloPduSender = null;
87 private ScheduledExecutorService exServiceHello = null;
88 private IsisInterfaceState interfaceState = IsisInterfaceState.DOWN;
89 private IsisLsdb isisLsdb = null;
90 private List<Ip4Address> allConfiguredInterfaceIps = null;
91 private Channel channel;
92
93 /**
94 * Returns ISIS LSDB instance.
95 *
96 * @return ISIS LSDB instance
97 */
98 public IsisLsdb isisLsdb() {
99 return isisLsdb;
100 }
101
102 /**
103 * Sets all configured interface IPs.
104 *
105 * @param allConfiguredInterfaces all configured interface IPs
106 */
107 public void setAllConfiguredInterfaceIps(List<Ip4Address> allConfiguredInterfaces) {
108 allConfiguredInterfaceIps = allConfiguredInterfaces;
109 }
110
111 /**
112 * Removes neighbor from the interface neighbor map.
113 *
114 * @param isisNeighbor ISIS neighbor instance
115 */
116 public void removeNeighbor(IsisNeighbor isisNeighbor) {
117 neighborList.remove(isisNeighbor.neighborMacAddress());
118 }
119
120 /**
121 * Returns the ISIS neighbor instance if exists.
122 *
123 * @param isisNeighborMac mac address of the neighbor router
124 * @return ISIS neighbor instance if exists else null
125 */
126 public IsisNeighbor lookup(MacAddress isisNeighborMac) {
127 return neighborList.get(isisNeighborMac);
128 }
129
130 /**
131 * Returns the neighbors list.
132 *
133 * @return neighbors list
134 */
135 public Set<MacAddress> neighbors() {
136 return neighborList.keySet();
137 }
138
139 /**
140 * Returns channel instance.
141 *
142 * @return channel instance
143 */
144 public Channel channel() {
145 return channel;
146 }
147
148 /**
149 * Returns interface index.
150 *
151 * @return interface index
152 */
153 public int interfaceIndex() {
154 return interfaceIndex;
155 }
156
157 /**
158 * Set interface index.
159 *
160 * @param interfaceIndex interface index
161 */
162 public void setInterfaceIndex(int interfaceIndex) {
163 this.interfaceIndex = interfaceIndex;
164 }
165
166 /**
167 * Returns the interface IP address.
168 *
169 * @return interface IP address
170 */
171 public Ip4Address interfaceIpAddress() {
172 return interfaceIpAddress;
173 }
174
175 /**
176 * Sets the interface IP address.
177 *
178 * @param interfaceIpAddress interfaceIpAddress interface IP address
179 */
180 public void setInterfaceIpAddress(Ip4Address interfaceIpAddress) {
181 this.interfaceIpAddress = interfaceIpAddress;
182 }
183
184 /**
185 * Returns the network mask.
186 *
187 * @return network mask
188 */
189 public byte[] networkMask() {
190 return networkMask;
191 }
192
193 /**
194 * Sets the network mask.
195 *
196 * @param networkMask network mask
197 */
198 public void setNetworkMask(byte[] networkMask) {
199 this.networkMask = networkMask;
200 }
201
202 /**
203 * Returns the interface mac address.
204 *
205 * @return interface mac address
206 */
207 public MacAddress getInterfaceMacAddress() {
208 return interfaceMacAddress;
209 }
210
211 /**
212 * Sets the interface mac address.
213 *
214 * @param interfaceMacAddress interface mac address
215 */
216 public void setInterfaceMacAddress(MacAddress interfaceMacAddress) {
217 this.interfaceMacAddress = interfaceMacAddress;
218 }
219
220 /**
221 * Returns intermediate system name.
222 *
223 * @return intermediate system name
224 */
225 public String intermediateSystemName() {
226 return intermediateSystemName;
227 }
228
229 /**
230 * Sets intermediate system name.
231 *
232 * @param intermediateSystemName intermediate system name
233 */
234 public void setIntermediateSystemName(String intermediateSystemName) {
235 this.intermediateSystemName = intermediateSystemName;
236 }
237
238 /**
239 * Returns system ID.
240 *
241 * @return system ID
242 */
243 public String systemId() {
244 return systemId;
245 }
246
247 /**
248 * Sets system ID.
249 *
250 * @param systemId system ID
251 */
252 public void setSystemId(String systemId) {
253 this.systemId = systemId;
254 }
255
256 /**
257 * Returns LAN ID.
258 *
259 * @return LAN ID
260 */
261 public String l1LanId() {
262 return l1LanId;
263 }
264
265 /**
266 * Sets LAN ID.
267 *
268 * @param l1LanId LAN ID
269 */
270 public void setL1LanId(String l1LanId) {
271 this.l1LanId = l1LanId;
272 }
273
274 /**
275 * Returns LAN ID.
276 *
277 * @return LAN ID
278 */
279 public String l2LanId() {
280 return l2LanId;
281 }
282
283 /**
284 * Sets LAN ID.
285 *
286 * @param l2LanId LAN ID
287 */
288 public void setL2LanId(String l2LanId) {
289 this.l2LanId = l2LanId;
290 }
291
292 /**
293 * Returns ID length.
294 *
295 * @return ID length
296 */
297 public int getIdLength() {
298
299 return ((idLength == 0) ? 6 : idLength);
300 }
301
302 /**
303 * Sets ID length.
304 *
305 * @param idLength ID length
306 */
307 public void setIdLength(int idLength) {
308 this.idLength = idLength;
309 }
310
311 /**
312 * Returns max area addresses.
313 *
314 * @return max area addresses
315 */
316 public int getMaxAreaAddresses() {
317
318 return maxAreaAddresses;
319 }
320
321 /**
322 * Sets area max addresses.
323 *
324 * @param maxAreaAddresses max area addresses
325 */
326 public void setMaxAreaAddresses(int maxAreaAddresses) {
327 this.maxAreaAddresses = maxAreaAddresses;
328 }
329
330 /**
331 * Returns reserved packet circuit type.
332 *
333 * @return reserved packet circuit type
334 */
335 public int reservedPacketCircuitType() {
336 return reservedPacketCircuitType;
337 }
338
339 /**
340 * Sets reserved packet circuit type.
341 *
342 * @param reservedPacketCircuitType reserved packet circuit type
343 */
344 public void setReservedPacketCircuitType(int reservedPacketCircuitType) {
345 this.reservedPacketCircuitType = reservedPacketCircuitType;
346 }
347
348 /**
349 * Returns point to point.
350 *
351 * @return point to point
352 */
353 public IsisNetworkType networkType() {
354 return networkType;
355 }
356
357 /**
358 * Sets point to point or broadcast.
359 *
360 * @param networkType point to point or broadcast
361 */
362 public void setNetworkType(IsisNetworkType networkType) {
363 this.networkType = networkType;
364 }
365
366 /**
367 * Returns area address.
368 *
369 * @return area address
370 */
371 public String areaAddress() {
372 return areaAddress;
373 }
374
375 /**
376 * Sets area address.
377 *
378 * @param areaAddress area address
379 */
380 public void setAreaAddress(String areaAddress) {
381 this.areaAddress = areaAddress;
382 }
383
384 /**
385 * Returns area length.
386 *
387 * @return area length
388 */
389 public int getAreaLength() {
390 return areaLength;
391 }
392
393 /**
394 * Sets area length.
395 *
396 * @param areaLength area length
397 */
398 public void setAreaLength(int areaLength) {
399 this.areaLength = areaLength;
400 }
401
402 /**
403 * Returns LSP ID.
404 *
405 * @return LSP ID
406 */
407 public String getLspId() {
408 return lspId;
409 }
410
411 /**
412 * Sets LSP ID.
413 *
414 * @param lspId link state packet ID
415 */
416 public void setLspId(String lspId) {
417 this.lspId = lspId;
418 }
419
420 /**
421 * Returns holding time.
422 *
423 * @return holding time
424 */
425 public int holdingTime() {
426 return holdingTime;
427 }
428
429 /**
430 * Sets holding time.
431 *
432 * @param holdingTime holding time
433 */
434 public void setHoldingTime(int holdingTime) {
435 this.holdingTime = holdingTime;
436 }
437
438 /**
439 * Returns priority.
440 *
441 * @return priority
442 */
443 public int priority() {
444 return priority;
445 }
446
447 /**
448 * Sets priority.
449 *
450 * @param priority priority
451 */
452 public void setPriority(int priority) {
453 this.priority = priority;
454 }
455
456 /**
457 * Returns hello interval.
458 *
459 * @return hello interval
460 */
461 public int helloInterval() {
462 return helloInterval;
463 }
464
465 /**
466 * Sets hello interval.
467 *
468 * @param helloInterval hello interval
469 */
470 public void setHelloInterval(int helloInterval) {
471 this.helloInterval = helloInterval;
472 }
473
474 /**
475 * Returns the interface state.
476 *
477 * @return interface state
478 */
479 public IsisInterfaceState interfaceState() {
480 return interfaceState;
481 }
482
483 /**
484 * Sets the interface state.
485 *
486 * @param interfaceState the interface state
487 */
488 public void setInterfaceState(IsisInterfaceState interfaceState) {
489 this.interfaceState = interfaceState;
490 }
491
492 /**
493 * Returns the circuit ID.
494 *
495 * @return circuit ID
496 */
497 public String circuitId() {
498 return circuitId;
499 }
500
501 /**
502 * Sets the circuit ID.
503 *
504 * @param circuitId circuit ID
505 */
506 public void setCircuitId(String circuitId) {
507 this.circuitId = circuitId;
508 }
509
510 /**
511 * Processes received ISIS message.
512 * When an ISIS message received it is handed over to this method.
513 * Based on the type of the ISIS message received it will be handed over
514 * to corresponding message handler methods.
515 *
516 * @param isisMessage received ISIS message
517 * @param isisLsdb ISIS LSDB instance
518 */
519 public void processIsisMessage(IsisMessage isisMessage, IsisLsdb isisLsdb, Channel channel) {
520 log.debug("IsisInterfaceImpl::processIsisMessage...!!!");
521 if (channel == null) {
522 this.channel = channel;
523 }
524 if (this.isisLsdb == null) {
525 this.isisLsdb = isisLsdb;
526 }
527
528 switch (isisMessage.isisPduType()) {
529 case L1HELLOPDU:
530 case L2HELLOPDU:
531 processL1L2HelloPduMessage(isisMessage, channel);
532 break;
533 case P2PHELLOPDU:
534 processP2pHelloPduMessage(isisMessage, channel);
535 break;
536 case L1LSPDU:
537 case L2LSPDU:
538 processLsPduMessage(isisMessage, channel);
539 break;
540 case L1CSNP:
541 case L2CSNP:
542 processCsnPduMessage(isisMessage, channel);
543 break;
544 case L1PSNP:
545 case L2PSNP:
546 log.debug("Received a PSNP packet...!!!");
547 break;
548 default:
549 log.debug("Unknown packet to process...!!!");
550 break;
551 }
552 }
553
554 /**
555 * Validates the received message.
556 *
557 * @param helloPdu ISIS message instance
558 * @return true if valid ISIS message else false
559 */
560 public boolean validateHelloMessage(HelloPdu helloPdu) {
561 boolean isValid = false;
562
563 //Local InterfaceAddress TLV and compare with the IP Interface address and check if they are in same subnet
564 List<Ip4Address> interfaceIpAddresses = helloPdu.interfaceIpAddresses();
565 Ip4Address neighborIp = (helloPdu.interfaceIpAddresses() != null) ?
566 interfaceIpAddresses.get(0) : Ip4Address.valueOf("0.0.0.0");
567 if (!IsisUtil.sameNetwork(interfaceIpAddress, neighborIp, networkMask)) {
568 return false;
569 }
570
571 //Verify if it's in same area, Areas which the router belongs to
572 List<String> areas = helloPdu.areaAddress();
573 for (String area : areas) {
574 if (areaAddress.equals(area)) {
575 isValid = true;
576 }
577 }
578
579 return isValid;
580 }
581
582 /**
583 * Checks neighbor presents in the list or not.
584 *
585 * @param neighborMac neighbor MAc address
586 * @return true if neighbor exist else false
587 */
588 private boolean isNeighborInList(MacAddress neighborMac) {
589 return neighborList.containsKey(neighborMac);
590 }
591
592 /**
593 * Adds neighbor in the list.
594 *
595 * @param neighbor neighbor MAC address
596 * @return true if neighbor exist else false
597 */
598 private void addNeighbouringRouter(IsisNeighbor neighbor) {
599 neighborList.put(neighbor.neighborMacAddress(), neighbor);
600 }
601
602 /**
603 * Returns neighbor presents in the list.
604 *
605 * @param neighborMac neighbor MAc address
606 * @return neighbor instance
607 */
608 private IsisNeighbor neighbouringRouter(MacAddress neighborMac) {
609 return neighborList.get(neighborMac);
610 }
611
612 /**
613 * Processes the L1 or L2 hello message.
614 *
615 * @param isisMessage hello message instance
616 * @param channel channel instance
617 */
618 public void processL1L2HelloPduMessage(IsisMessage isisMessage, Channel channel) {
619 log.debug("Enters processL1L2HelloPduMessage ...!!!");
620 log.debug("IsisInterfaceImpl::processHelloMessage...!!!");
621
622 L1L2HelloPdu helloPacket = (L1L2HelloPdu) isisMessage;
623 log.debug("IsisInterfaceImpl::processHelloMessage::Interface Type {} ISISInterfaceState {} ",
624 networkType, interfaceState);
625
626 //If L1 Hello, validate the area, network and max address
627 if (IsisPduType.get(helloPacket.pduType()) == IsisPduType.L1HELLOPDU &&
628 !validateHelloMessage(helloPacket)) {
629 return;
630 }
631
632 //Get the neighbor
633 IsisNeighbor neighbor = neighbouringRouter(isisMessage.sourceMac());
634 //Neighbor is not in list
635 if (!isNeighborInList(isisMessage.sourceMac())) {
636 neighbor = new DefaultIsisNeighbor(helloPacket, this);
637 addNeighbouringRouter(neighbor);
638 }
639
640 neighbor.stopInactivityTimeCheck();
641 neighbor.startInactivityTimeCheck();
642
643 //Assign the DIS
644 String lanId = helloPacket.lanId();
645
646 if (IsisPduType.L1HELLOPDU == helloPacket.isisPduType()) {
647 buildUpdateAndSendSelfGeneratedLspIfDisChange(l1LanId, lanId, channel);
648 l1LanId = lanId;
649 neighbor.setL1LanId(lanId);
650 //if a change in lanid
651 } else if (IsisPduType.L2HELLOPDU == helloPacket.isisPduType()) {
652 buildUpdateAndSendSelfGeneratedLspIfDisChange(l1LanId, lanId, channel);
653 l2LanId = lanId;
654 neighbor.setL2LanId(lanId);
655 }
656
657 //Check in neighbors list our MAC address present
658 List<MacAddress> neighbors = helloPacket.neighborList();
659 for (MacAddress macAddress : neighbors) {
660 if (interfaceMacAddress.equals(macAddress)) {
661 neighbor.setNeighborState(IsisInterfaceState.UP);
662 //Build Self LSP add in LSDB and sent it.
663 buildStoreAndSendSelfGeneratedLspIfNotExistInDb(channel);
664 break;
665 }
666 }
667 }
668
669 /**
670 * Builds and store and send self generated LSP.
671 *
672 * @param channel netty channel instance
673 */
674 private void buildStoreAndSendSelfGeneratedLspIfNotExistInDb(Channel channel) {
675 //Check our LSP is present in DB. else create a self LSP and store it and sent it
676 String lspKey = isisLsdb.lspKey(systemId);
677 LspWrapper wrapper = null;
678 if (reservedPacketCircuitType == IsisRouterType.L1.value()) {
679 wrapper = isisLsdb.findLsp(IsisPduType.L1LSPDU, lspKey);
680 if (wrapper == null) {
681 LsPdu lsp = new LspGenerator().getLsp(this, lspKey, IsisPduType.L1LSPDU, allConfiguredInterfaceIps);
682 isisLsdb.addLsp(lsp, true, this);
683 sendLsp(lsp, channel);
684 }
685 } else if (reservedPacketCircuitType == IsisRouterType.L2.value()) {
686 wrapper = isisLsdb.findLsp(IsisPduType.L2LSPDU, lspKey);
687 if (wrapper == null) {
688 LsPdu lsp = new LspGenerator().getLsp(this, lspKey, IsisPduType.L2LSPDU, allConfiguredInterfaceIps);
689 isisLsdb.addLsp(lsp, true, this);
690 sendLsp(lsp, channel);
691 }
692 } else if (reservedPacketCircuitType == IsisRouterType.L1L2.value()) {
693 wrapper = isisLsdb.findLsp(IsisPduType.L1LSPDU, lspKey);
694 if (wrapper == null) {
695 LsPdu lsp = new LspGenerator().getLsp(this, lspKey, IsisPduType.L1LSPDU, allConfiguredInterfaceIps);
696 isisLsdb.addLsp(lsp, true, this);
697 sendLsp(lsp, channel);
698 }
699
700 wrapper = isisLsdb.findLsp(IsisPduType.L2LSPDU, lspKey);
701 if (wrapper == null) {
702 LsPdu lsp = new LspGenerator().getLsp(this, lspKey, IsisPduType.L2LSPDU, allConfiguredInterfaceIps);
703 isisLsdb.addLsp(lsp, true, this);
704 sendLsp(lsp, channel);
705 }
706 }
707 }
708
709 /**
710 * Builds and update in DB and send self generated LSP.
711 *
712 * @param previousLanId previous DIS ID
713 * @param latestLanId latest DIS ID
714 * @param channel netty channel instance
715 */
716 private void buildUpdateAndSendSelfGeneratedLspIfDisChange(String previousLanId,
717 String latestLanId, Channel channel) {
718 //If DIS change then build and sent LSP
719 if (previousLanId != null && !previousLanId.equals(IsisConstants.DEFAULTLANID) &&
720 !previousLanId.equals(latestLanId)) {
721 //Create a self LSP and Update it in DB and sent it
722 String lspKey = isisLsdb.lspKey(systemId);
723 if (reservedPacketCircuitType == IsisRouterType.L1.value()) {
724 LsPdu lsp = new LspGenerator().getLsp(this, lspKey, IsisPduType.L1LSPDU, allConfiguredInterfaceIps);
725 isisLsdb.addLsp(lsp, true, this);
726 sendLsp(lsp, channel);
727 } else if (reservedPacketCircuitType == IsisRouterType.L2.value()) {
728 LsPdu lsp = new LspGenerator().getLsp(this, lspKey, IsisPduType.L2LSPDU, allConfiguredInterfaceIps);
729 isisLsdb.addLsp(lsp, true, this);
730 sendLsp(lsp, channel);
731 } else if (reservedPacketCircuitType == IsisRouterType.L1L2.value()) {
732 //L1 LSPDU
733 LsPdu lsp = new LspGenerator().getLsp(this, lspKey, IsisPduType.L1LSPDU, allConfiguredInterfaceIps);
734 isisLsdb.addLsp(lsp, true, this);
735 sendLsp(lsp, channel);
736 //L1 LSPDU
737 lsp = new LspGenerator().getLsp(this, lspKey, IsisPduType.L2LSPDU, allConfiguredInterfaceIps);
738 isisLsdb.addLsp(lsp, true, this);
739 sendLsp(lsp, channel);
740 }
741 }
742
743 }
744
745 /**
746 * Sends LS PDU message to channel.
747 *
748 * @param lsp LS PDU message instance
749 * @param channel channel instance
750 */
751 private void sendLsp(LsPdu lsp, Channel channel) {
752 byte[] lspBytes = lsp.asBytes();
753 lspBytes = IsisUtil.addLengthAndMarkItInReserved(lspBytes, IsisConstants.LENGTHPOSITION,
754 IsisConstants.LENGTHPOSITION + 1,
755 IsisConstants.RESERVEDPOSITION);
756 lspBytes = IsisUtil.addChecksum(lspBytes, IsisConstants.CHECKSUMPOSITION,
757 IsisConstants.CHECKSUMPOSITION + 1);
758 //write to the channel
759 channel.write(IsisUtil.framePacket(lspBytes, interfaceIndex));
760 }
761
762 /**
763 * Processes P2P hello message.
764 *
765 * @param isisMessage hello message instance
766 * @param channel channel instance
767 */
768 public void processP2pHelloPduMessage(IsisMessage isisMessage, Channel channel) {
769 log.debug("Enters processP2pHelloPduMessage ...!!!");
770 P2PHelloPdu helloPacket = (P2PHelloPdu) isisMessage;
771
772 log.debug("IsisInterfaceImpl::processHelloMessage::Interface Type {} OSPFInterfaceState {} ",
773 networkType, interfaceState);
774
775 //validate the area, network and max address
776 if (!validateHelloMessage(helloPacket)) {
777 return;
778 }
779
780 IsisNeighbor neighbor = null;
781 List<IsisTlv> tlvs = ((P2PHelloPdu) isisMessage).tlvs();
782 AdjacencyStateTlv stateTlv = null;
783 for (IsisTlv tlv : tlvs) {
784 if (tlv instanceof AdjacencyStateTlv) {
785 stateTlv = (AdjacencyStateTlv) tlv;
786 break;
787 }
788 }
789
790 if (stateTlv == null) {
791 neighbor = neighbouringRouter(isisMessage.sourceMac());
792 if (neighbor == null) {
793 neighbor = new DefaultIsisNeighbor(helloPacket, this);
794 addNeighbouringRouter(neighbor);
795 }
796 neighbor.setNeighborState(IsisInterfaceState.DOWN);
797 buildStoreAndSendSelfGeneratedLspIfNotExistInDb(channel);
798 } else if (stateTlv.adjacencyType() == IsisInterfaceState.DOWN.value()) {
799 neighbor = neighbouringRouter(isisMessage.sourceMac());
800 if (neighbor == null) {
801 neighbor = new DefaultIsisNeighbor(helloPacket, this);
802 addNeighbouringRouter(neighbor);
803 }
804 neighbor.setLocalExtendedCircuitId(stateTlv.localCircuitId());
805 } else if (stateTlv.adjacencyType() == IsisInterfaceState.INITIAL.value()) {
806 //Neighbor already present in the list
807 neighbor = neighbouringRouter(isisMessage.sourceMac());
808 neighbor.setNeighborState(IsisInterfaceState.INITIAL);
809 neighbor.setLocalExtendedCircuitId(stateTlv.localCircuitId());
810 //interfaceState = IsisInterfaceState.UP;
811 } else if (stateTlv.adjacencyType() == IsisInterfaceState.UP.value()) {
812 //Build Self LSP add in LSDB and sent it.
813 neighbor = neighbouringRouter(isisMessage.sourceMac());
814 neighbor.setNeighborState(IsisInterfaceState.UP);
815 neighbor.setLocalExtendedCircuitId(stateTlv.localCircuitId());
816 buildStoreAndSendSelfGeneratedLspIfNotExistInDb(channel);
817 }
818
819 neighbor.stopInactivityTimeCheck();
820 neighbor.startInactivityTimeCheck();
821 }
822
823 /**
824 * Processes LS PDU message.
825 *
826 * @param isisMessage LS pdu message instance
827 * @param channel channel instance
828 */
829 public void processLsPduMessage(IsisMessage isisMessage, Channel channel) {
830 log.debug("Enters processLsPduMessage ...!!!");
831 LsPdu lsPdu = (LsPdu) isisMessage;
832 LspWrapper wrapper = isisLsdb.findLsp(lsPdu.isisPduType(), lsPdu.lspId());
833 if (wrapper == null || isisLsdb.isNewerOrSameLsp(lsPdu, wrapper.lsPdu()).equalsIgnoreCase("latest")) {
834 //not exist in the database or latest, then add it in database
835 isisLsdb.addLsp(lsPdu, false, this);
836 }
837
838 //If network type is P2P, acknowledge with a PSNP
839 if (networkType() == IsisNetworkType.P2P) {
840 IsisPduType psnpType = null;
841 if (IsisPduType.get(lsPdu.pduType()) == IsisPduType.L1LSPDU) {
842 psnpType = IsisPduType.L1PSNP;
843 } else if (IsisPduType.get(lsPdu.pduType()) == IsisPduType.L2LSPDU) {
844 psnpType = IsisPduType.L2PSNP;
845 }
846 IsisHeader isisHeader = new LspGenerator().getHeader(psnpType);
847 Psnp psnp = new Psnp(isisHeader);
848 psnp.setSourceId(lspKeyP2P(this.systemId));
849 TlvHeader tlvHeader = new TlvHeader();
850 tlvHeader.setTlvType(TlvType.LSPENTRY.value());
851 tlvHeader.setTlvLength(0);
852 LspEntriesTlv lspEntriesTlv = new LspEntriesTlv(tlvHeader);
853 LspEntry lspEntry = new LspEntry();
854 lspEntry.setLspChecksum(lsPdu.checkSum());
855 lspEntry.setLspId(lsPdu.lspId());
856 lspEntry.setLspSequenceNumber(lsPdu.sequenceNumber());
857 lspEntry.setRemainingTime(lsPdu.remainingLifeTime());
858 lspEntriesTlv.addLspEntry(lspEntry);
859 psnp.addTlv(lspEntriesTlv);
860
861 //write it to channel buffer.
862 byte[] psnpBytes = psnp.asBytes();
863 psnpBytes = IsisUtil.addLengthAndMarkItInReserved(psnpBytes, IsisConstants.LENGTHPOSITION,
864 IsisConstants.LENGTHPOSITION + 1,
865 IsisConstants.RESERVEDPOSITION);
866 flagValue = false;
867 //write to the channel
868 channel.write(IsisUtil.framePacket(psnpBytes, interfaceIndex));
869 }
870 }
871
872 /**
873 * Processes CSN PDU message.
874 *
875 * @param isisMessage CSN PDU message instance
876 * @param channel channel instance
877 */
878 public void processCsnPduMessage(IsisMessage isisMessage, Channel channel) {
879 log.debug("Enters processCsnPduMessage ...!!!");
880 if (reservedPacketCircuitType == IsisRouterType.L1.value()) {
881 processOnL1CsnPdu(isisMessage, channel);
882 } else if (reservedPacketCircuitType == IsisRouterType.L2.value()) {
883 processOnL2CsnPdu(isisMessage, channel);
884 }
885 }
886
887 /**
888 * Process the isisMessage which belongs to L1 CSN PDU.
889 * checks the database for this LsPdu if it exists further check for sequence number
890 * sequence number is greater will send PsnPdu.
891 *
892 * @param isisMessage CSN PDU message instance
893 * @param channel netty channel instance
894 */
895 private void processOnL1CsnPdu(IsisMessage isisMessage, Channel channel) {
896 Csnp csnPacket = (Csnp) isisMessage;
897 List<LspEntry> lspEntryRequestList = new ArrayList<>();
898 boolean selfOriginatedFound = false;
899 if (IsisPduType.L1CSNP.equals(csnPacket.isisPduType())) {
900 List<IsisTlv> isisTlvs = csnPacket.getAllTlv();
901 Iterator iterator = isisTlvs.iterator();
902 while (iterator.hasNext()) {
903 IsisTlv isisTlv = (IsisTlv) iterator.next();
904 if (isisTlv instanceof LspEntriesTlv) {
905 LspEntriesTlv lspEntriesTlv = (LspEntriesTlv) isisTlv;
906 List<LspEntry> lspEntryList = lspEntriesTlv.lspEntry();
907 Iterator lspEntryListIterator = lspEntryList.iterator();
908 while (lspEntryListIterator.hasNext()) {
909 LspEntry lspEntry = (LspEntry) lspEntryListIterator.next();
910 String lspKey = lspEntry.lspId();
911 LspWrapper lspWrapper = isisLsdb.findLsp(IsisPduType.L1LSPDU, lspKey);
912 if (lspWrapper != null) {
913 LsPdu lsPdu = (LsPdu) lspWrapper.lsPdu();
914 if (lspWrapper.isSelfOriginated()) {
915 selfOriginatedFound = true;
916 if (lspEntry.lspSequenceNumber() > lsPdu.sequenceNumber()) {
917 sendLsPduMessage(lspEntry.lspSequenceNumber(), csnPacket.isisPduType(), channel);
918 }
919 } else {
920 if (lsPdu.sequenceNumber() < lspEntry.lspSequenceNumber()) {
921 lspEntryRequestList.add(lspEntry);
922 flagValue = true;
923 }
924 }
925 } else {
926 lspEntryRequestList.add(lspEntry);
927 flagValue = true;
928 }
929 }
930 }
931 }
932 if (flagValue) {
933 sendPsnPduMessage(lspEntryRequestList, csnPacket.isisPduType(), channel);
934 }
935
936 if (!selfOriginatedFound) {
937 String lspKey = isisLsdb.lspKey(systemId);
938 LspWrapper wrapper = isisLsdb.findLsp(IsisPduType.L1LSPDU, lspKey);
939 sendLsp((LsPdu) wrapper.lsPdu(), channel);
940 }
941 }
942 }
943
944 /**
945 * Process the isisMessage which belongs to L2 CSNP.
946 * checks the database for this LsPdu if it exists further check for sequence number
947 * sequence number is greater will send PsnPdu.
948 *
949 * @param isisMessage received CSNP message
950 * @param channel netty channel instance
951 */
952 private void processOnL2CsnPdu(IsisMessage isisMessage, Channel channel) {
953 Csnp csnPacket = (Csnp) isisMessage;
954 List<LspEntry> lspEntryRequestList = new ArrayList<>();
955 boolean selfOriginatedFound = false;
956 if (IsisPduType.L2CSNP.equals(csnPacket.isisPduType())) {
957 List<IsisTlv> isisTlvs = csnPacket.getAllTlv();
958 Iterator iterator = isisTlvs.iterator();
959 while (iterator.hasNext()) {
960 IsisTlv isisTlv = (IsisTlv) iterator.next();
961 if (isisTlv instanceof LspEntriesTlv) {
962 LspEntriesTlv lspEntriesTlv = (LspEntriesTlv) isisTlv;
963 List<LspEntry> lspEntryList = lspEntriesTlv.lspEntry();
964 Iterator lspEntryListIterator = lspEntryList.iterator();
965 while (lspEntryListIterator.hasNext()) {
966 LspEntry lspEntry = (LspEntry) lspEntryListIterator.next();
967 String lspKey = lspEntry.lspId();
968 LspWrapper lspWrapper = isisLsdb.findLsp(IsisPduType.L2LSPDU, lspKey);
969 if (lspWrapper != null) {
970 LsPdu lsPdu = (LsPdu) lspWrapper.lsPdu();
971 if (lspWrapper.isSelfOriginated()) {
972 selfOriginatedFound = true;
973 if (lspEntry.lspSequenceNumber() > lsPdu.sequenceNumber()) {
974 sendLsPduMessage(lspEntry.lspSequenceNumber(), csnPacket.isisPduType(), channel);
975 }
976 } else {
977 if (lsPdu.sequenceNumber() < lspEntry.lspSequenceNumber()) {
978 lspEntryRequestList.add(lspEntry);
979 flagValue = true;
980 }
981 }
982 } else {
983 lspEntryRequestList.add(lspEntry);
984 flagValue = true;
985 }
986 }
987 }
988 }
989 if (flagValue) {
990 sendPsnPduMessage(lspEntryRequestList, csnPacket.isisPduType(), channel);
991 lspEntryRequestList.clear();
992 }
993
994 if (!selfOriginatedFound) {
995 String lspKey = isisLsdb.lspKey(systemId);
996 LspWrapper wrapper = isisLsdb.findLsp(IsisPduType.L2LSPDU, lspKey);
997 sendLsp((LsPdu) wrapper.lsPdu(), channel);
998 }
999 }
1000 }
1001
1002 /**
1003 * Sends the partial sequence number PDU.
1004 *
1005 * @param lspEntryRequestList list of lsp entry request
1006 * @param isisPduType intermediate system PDU type
1007 * @param channel netty channel instance
1008 */
1009 private void sendPsnPduMessage(List<LspEntry> lspEntryRequestList, IsisPduType isisPduType, Channel channel) {
1010 IsisPduType psnpType = null;
1011 if (isisPduType == IsisPduType.L1CSNP) {
1012 psnpType = IsisPduType.L1PSNP;
1013 } else if (reservedPacketCircuitType == IsisRouterType.L2.value()) {
1014 psnpType = IsisPduType.L2PSNP;
1015 }
1016 IsisHeader isisHeader = new LspGenerator().getHeader(psnpType);
1017 Psnp psnp = new Psnp(isisHeader);
1018 psnp.setSourceId(lspKeyP2P(this.systemId));
1019 TlvHeader tlvHeader = new TlvHeader();
1020 tlvHeader.setTlvType(TlvType.LSPENTRY.value());
1021 tlvHeader.setTlvLength(0);
1022 LspEntriesTlv lspEntriesTlv = new LspEntriesTlv(tlvHeader);
1023 for (LspEntry lspEntry : lspEntryRequestList) {
1024 lspEntriesTlv.addLspEntry(lspEntry);
1025 }
1026 psnp.addTlv(lspEntriesTlv);
1027 //write it to channel buffer.
1028 byte[] psnpBytes = psnp.asBytes();
1029 psnpBytes = IsisUtil.addLengthAndMarkItInReserved(psnpBytes, IsisConstants.LENGTHPOSITION,
1030 IsisConstants.LENGTHPOSITION + 1,
1031 IsisConstants.RESERVEDPOSITION);
1032 flagValue = false;
1033 //write to the channel
1034 channel.write(IsisUtil.framePacket(psnpBytes, interfaceIndex));
1035 }
1036
1037 /**
1038 * Gets the LSP key.
1039 *
1040 * @param systemId system ID
1041 * @return key
1042 */
1043 public String lspKeyP2P(String systemId) {
1044 StringBuilder lspKey = new StringBuilder();
1045 lspKey.append(systemId);
1046 lspKey.append(".00");
1047 return lspKey.toString();
1048 }
1049
1050 /**
1051 * Sends the link state PDU with latest self generated lsp entry.
1052 *
1053 * @param sequenceNumber sequence number of the self generated lsp
1054 * @param isisPduType intermediate system type
1055 * @param channel netty channel instance
1056 */
1057 private void sendLsPduMessage(int sequenceNumber, IsisPduType isisPduType, Channel channel) {
1058 String lspKey = isisLsdb.lspKey(systemId);
1059 LsPdu lsp = new LspGenerator().getLsp(this, lspKey, isisPduType, allConfiguredInterfaceIps);
1060 lsp.setSequenceNumber(sequenceNumber);
1061 byte[] lspBytes = lsp.asBytes();
1062 lspBytes = IsisUtil.addLengthAndMarkItInReserved(lspBytes, IsisConstants.LENGTHPOSITION,
1063 IsisConstants.LENGTHPOSITION + 1,
1064 IsisConstants.RESERVEDPOSITION);
1065 lspBytes = IsisUtil.addChecksum(lspBytes, IsisConstants.CHECKSUMPOSITION,
1066 IsisConstants.CHECKSUMPOSITION + 1);
1067 //write to the channel
1068 channel.write(IsisUtil.framePacket(lspBytes, interfaceIndex));
1069 }
1070
1071
1072 /**
1073 * Starts the hello timer which sends hello packet every configured seconds.
1074 *
1075 * @param channel netty channel instance
1076 */
1077 public void startHelloSender(Channel channel) {
1078 log.debug("IsisInterfaceImpl::startHelloSender");
1079
1080 isisHelloPduSender = new IsisHelloPduSender(channel, this);
1081 exServiceHello = Executors.newSingleThreadScheduledExecutor();
1082 final ScheduledFuture<?> helloHandle =
1083 exServiceHello.scheduleAtFixedRate(isisHelloPduSender, 0,
1084 helloInterval, TimeUnit.SECONDS);
1085 }
1086}