blob: 864b6e5aa374fb6dc8b4533a7e7706dc3b36e04b [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;
sunish vk4b5ce002016-05-09 20:18:35 +053072 private String l1LanId = IsisConstants.DEFAULTLANID;
73 private String l2LanId = IsisConstants.DEFAULTLANID;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +053074 private int idLength;
75 private int maxAreaAddresses;
76 private int reservedPacketCircuitType;
77 private IsisNetworkType networkType;
78 private String areaAddress;
79 private int areaLength;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +053080 private int holdingTime;
81 private int priority;
82 private String circuitId;
83 private int helloInterval;
84 private Map<MacAddress, IsisNeighbor> neighborList = new ConcurrentHashMap<>();
85 private IsisHelloPduSender isisHelloPduSender = null;
86 private ScheduledExecutorService exServiceHello = null;
87 private IsisInterfaceState interfaceState = IsisInterfaceState.DOWN;
88 private IsisLsdb isisLsdb = null;
89 private List<Ip4Address> allConfiguredInterfaceIps = null;
90 private Channel channel;
sunish vkc3824e82016-05-11 19:38:24 +053091 private boolean helloSenderStarted = false;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +053092
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) {
sunish vk4b5ce002016-05-09 20:18:35 +0530117 log.debug("Neighbor removed - {}", isisNeighbor.neighborMacAddress());
118 isisNeighbor.stopHoldingTimeCheck();
119 isisNeighbor.stopInactivityTimeCheck();
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530120 neighborList.remove(isisNeighbor.neighborMacAddress());
121 }
122
123 /**
sunish vk4b5ce002016-05-09 20:18:35 +0530124 * Removes all the neighbors.
125 */
126 public void removeNeighbors() {
127 Set<MacAddress> neighbors = neighbors();
128 for (MacAddress mac : neighbors) {
129 removeNeighbor(lookup(mac));
130 log.debug("Neighbor removed - {}", mac);
131 }
132 neighborList.clear();
133 }
134
135 /**
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530136 * Returns the ISIS neighbor instance if exists.
137 *
138 * @param isisNeighborMac mac address of the neighbor router
139 * @return ISIS neighbor instance if exists else null
140 */
141 public IsisNeighbor lookup(MacAddress isisNeighborMac) {
142 return neighborList.get(isisNeighborMac);
143 }
144
145 /**
146 * Returns the neighbors list.
147 *
148 * @return neighbors list
149 */
150 public Set<MacAddress> neighbors() {
151 return neighborList.keySet();
152 }
153
154 /**
155 * Returns channel instance.
156 *
157 * @return channel instance
158 */
159 public Channel channel() {
160 return channel;
161 }
162
163 /**
164 * Returns interface index.
165 *
166 * @return interface index
167 */
168 public int interfaceIndex() {
169 return interfaceIndex;
170 }
171
172 /**
173 * Set interface index.
174 *
175 * @param interfaceIndex interface index
176 */
177 public void setInterfaceIndex(int interfaceIndex) {
178 this.interfaceIndex = interfaceIndex;
179 }
180
181 /**
182 * Returns the interface IP address.
183 *
184 * @return interface IP address
185 */
186 public Ip4Address interfaceIpAddress() {
187 return interfaceIpAddress;
188 }
189
190 /**
191 * Sets the interface IP address.
192 *
193 * @param interfaceIpAddress interfaceIpAddress interface IP address
194 */
195 public void setInterfaceIpAddress(Ip4Address interfaceIpAddress) {
196 this.interfaceIpAddress = interfaceIpAddress;
197 }
198
199 /**
200 * Returns the network mask.
201 *
202 * @return network mask
203 */
204 public byte[] networkMask() {
205 return networkMask;
206 }
207
208 /**
209 * Sets the network mask.
210 *
211 * @param networkMask network mask
212 */
213 public void setNetworkMask(byte[] networkMask) {
214 this.networkMask = networkMask;
215 }
216
217 /**
218 * Returns the interface mac address.
219 *
220 * @return interface mac address
221 */
222 public MacAddress getInterfaceMacAddress() {
223 return interfaceMacAddress;
224 }
225
226 /**
227 * Sets the interface mac address.
228 *
229 * @param interfaceMacAddress interface mac address
230 */
231 public void setInterfaceMacAddress(MacAddress interfaceMacAddress) {
232 this.interfaceMacAddress = interfaceMacAddress;
233 }
234
235 /**
236 * Returns intermediate system name.
237 *
238 * @return intermediate system name
239 */
240 public String intermediateSystemName() {
241 return intermediateSystemName;
242 }
243
244 /**
245 * Sets intermediate system name.
246 *
247 * @param intermediateSystemName intermediate system name
248 */
249 public void setIntermediateSystemName(String intermediateSystemName) {
250 this.intermediateSystemName = intermediateSystemName;
251 }
252
253 /**
254 * Returns system ID.
255 *
256 * @return system ID
257 */
258 public String systemId() {
259 return systemId;
260 }
261
262 /**
263 * Sets system ID.
264 *
265 * @param systemId system ID
266 */
267 public void setSystemId(String systemId) {
268 this.systemId = systemId;
269 }
270
271 /**
272 * Returns LAN ID.
273 *
274 * @return LAN ID
275 */
276 public String l1LanId() {
277 return l1LanId;
278 }
279
280 /**
281 * Sets LAN ID.
282 *
283 * @param l1LanId LAN ID
284 */
285 public void setL1LanId(String l1LanId) {
286 this.l1LanId = l1LanId;
287 }
288
289 /**
290 * Returns LAN ID.
291 *
292 * @return LAN ID
293 */
294 public String l2LanId() {
295 return l2LanId;
296 }
297
298 /**
299 * Sets LAN ID.
300 *
301 * @param l2LanId LAN ID
302 */
303 public void setL2LanId(String l2LanId) {
304 this.l2LanId = l2LanId;
305 }
306
307 /**
308 * Returns ID length.
309 *
310 * @return ID length
311 */
312 public int getIdLength() {
313
314 return ((idLength == 0) ? 6 : idLength);
315 }
316
317 /**
318 * Sets ID length.
319 *
320 * @param idLength ID length
321 */
322 public void setIdLength(int idLength) {
323 this.idLength = idLength;
324 }
325
326 /**
327 * Returns max area addresses.
328 *
329 * @return max area addresses
330 */
331 public int getMaxAreaAddresses() {
332
333 return maxAreaAddresses;
334 }
335
336 /**
337 * Sets area max addresses.
338 *
339 * @param maxAreaAddresses max area addresses
340 */
341 public void setMaxAreaAddresses(int maxAreaAddresses) {
342 this.maxAreaAddresses = maxAreaAddresses;
343 }
344
345 /**
346 * Returns reserved packet circuit type.
347 *
348 * @return reserved packet circuit type
349 */
350 public int reservedPacketCircuitType() {
351 return reservedPacketCircuitType;
352 }
353
354 /**
355 * Sets reserved packet circuit type.
356 *
357 * @param reservedPacketCircuitType reserved packet circuit type
358 */
359 public void setReservedPacketCircuitType(int reservedPacketCircuitType) {
360 this.reservedPacketCircuitType = reservedPacketCircuitType;
361 }
362
363 /**
364 * Returns point to point.
365 *
366 * @return point to point
367 */
368 public IsisNetworkType networkType() {
369 return networkType;
370 }
371
372 /**
373 * Sets point to point or broadcast.
374 *
375 * @param networkType point to point or broadcast
376 */
377 public void setNetworkType(IsisNetworkType networkType) {
378 this.networkType = networkType;
379 }
380
381 /**
382 * Returns area address.
383 *
384 * @return area address
385 */
386 public String areaAddress() {
387 return areaAddress;
388 }
389
390 /**
391 * Sets area address.
392 *
393 * @param areaAddress area address
394 */
395 public void setAreaAddress(String areaAddress) {
396 this.areaAddress = areaAddress;
397 }
398
399 /**
400 * Returns area length.
401 *
402 * @return area length
403 */
404 public int getAreaLength() {
405 return areaLength;
406 }
407
408 /**
409 * Sets area length.
410 *
411 * @param areaLength area length
412 */
413 public void setAreaLength(int areaLength) {
414 this.areaLength = areaLength;
415 }
416
417 /**
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530418 * Returns holding time.
419 *
420 * @return holding time
421 */
422 public int holdingTime() {
423 return holdingTime;
424 }
425
426 /**
427 * Sets holding time.
428 *
429 * @param holdingTime holding time
430 */
431 public void setHoldingTime(int holdingTime) {
432 this.holdingTime = holdingTime;
433 }
434
435 /**
436 * Returns priority.
437 *
438 * @return priority
439 */
440 public int priority() {
441 return priority;
442 }
443
444 /**
445 * Sets priority.
446 *
447 * @param priority priority
448 */
449 public void setPriority(int priority) {
450 this.priority = priority;
451 }
452
453 /**
454 * Returns hello interval.
455 *
456 * @return hello interval
457 */
458 public int helloInterval() {
459 return helloInterval;
460 }
461
462 /**
463 * Sets hello interval.
464 *
465 * @param helloInterval hello interval
466 */
467 public void setHelloInterval(int helloInterval) {
468 this.helloInterval = helloInterval;
469 }
470
471 /**
472 * Returns the interface state.
473 *
474 * @return interface state
475 */
476 public IsisInterfaceState interfaceState() {
477 return interfaceState;
478 }
479
480 /**
481 * Sets the interface state.
482 *
483 * @param interfaceState the interface state
484 */
485 public void setInterfaceState(IsisInterfaceState interfaceState) {
486 this.interfaceState = interfaceState;
487 }
488
489 /**
490 * Returns the circuit ID.
491 *
492 * @return circuit ID
493 */
494 public String circuitId() {
495 return circuitId;
496 }
497
498 /**
499 * Sets the circuit ID.
500 *
501 * @param circuitId circuit ID
502 */
503 public void setCircuitId(String circuitId) {
504 this.circuitId = circuitId;
505 }
506
507 /**
508 * Processes received ISIS message.
509 * When an ISIS message received it is handed over to this method.
510 * Based on the type of the ISIS message received it will be handed over
511 * to corresponding message handler methods.
512 *
513 * @param isisMessage received ISIS message
514 * @param isisLsdb ISIS LSDB instance
515 */
516 public void processIsisMessage(IsisMessage isisMessage, IsisLsdb isisLsdb, Channel channel) {
517 log.debug("IsisInterfaceImpl::processIsisMessage...!!!");
sunish vk4b5ce002016-05-09 20:18:35 +0530518 this.channel = channel;
519
520 if (isisMessage.sourceMac().equals(interfaceMacAddress)) {
521 log.debug("Received our own message {}...!!!", isisMessage.isisPduType());
522 return;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530523 }
sunish vk4b5ce002016-05-09 20:18:35 +0530524
525 if (isisMessage.isisPduType() == IsisPduType.P2PHELLOPDU && networkType.equals(IsisNetworkType.BROADCAST)) {
526 return;
527 } else if ((isisMessage.isisPduType() == IsisPduType.L1HELLOPDU ||
528 isisMessage.isisPduType() == IsisPduType.L2HELLOPDU)
529 && networkType.equals(IsisNetworkType.P2P)) {
530 return;
531 }
532
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530533 if (this.isisLsdb == null) {
534 this.isisLsdb = isisLsdb;
535 }
536
537 switch (isisMessage.isisPduType()) {
538 case L1HELLOPDU:
539 case L2HELLOPDU:
540 processL1L2HelloPduMessage(isisMessage, channel);
541 break;
542 case P2PHELLOPDU:
543 processP2pHelloPduMessage(isisMessage, channel);
544 break;
545 case L1LSPDU:
546 case L2LSPDU:
547 processLsPduMessage(isisMessage, channel);
548 break;
549 case L1CSNP:
550 case L2CSNP:
551 processCsnPduMessage(isisMessage, channel);
552 break;
553 case L1PSNP:
554 case L2PSNP:
sunish vk4b5ce002016-05-09 20:18:35 +0530555 processPsnPduMessage(isisMessage, channel);
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530556 break;
557 default:
558 log.debug("Unknown packet to process...!!!");
559 break;
560 }
561 }
562
563 /**
564 * Validates the received message.
565 *
566 * @param helloPdu ISIS message instance
567 * @return true if valid ISIS message else false
568 */
569 public boolean validateHelloMessage(HelloPdu helloPdu) {
570 boolean isValid = false;
571
sunish vk4b5ce002016-05-09 20:18:35 +0530572 if ((helloPdu.circuitType() == IsisRouterType.L1.value() &&
573 reservedPacketCircuitType == IsisRouterType.L2.value()) ||
574 (helloPdu.circuitType() == IsisRouterType.L2.value() &&
575 reservedPacketCircuitType == IsisRouterType.L1.value())) {
576 return false;
577 }
578
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530579 //Local InterfaceAddress TLV and compare with the IP Interface address and check if they are in same subnet
580 List<Ip4Address> interfaceIpAddresses = helloPdu.interfaceIpAddresses();
581 Ip4Address neighborIp = (helloPdu.interfaceIpAddresses() != null) ?
582 interfaceIpAddresses.get(0) : Ip4Address.valueOf("0.0.0.0");
583 if (!IsisUtil.sameNetwork(interfaceIpAddress, neighborIp, networkMask)) {
584 return false;
585 }
586
587 //Verify if it's in same area, Areas which the router belongs to
sunish vk4b5ce002016-05-09 20:18:35 +0530588 if (helloPdu.circuitType() == IsisRouterType.L1.value()) {
589 List<String> areas = helloPdu.areaAddress();
590 for (String area : areas) {
591 if (areaAddress.equals(area)) {
592 isValid = true;
593 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530594 }
sunish vk4b5ce002016-05-09 20:18:35 +0530595 } else if (helloPdu.circuitType() == IsisRouterType.L2.value() ||
596 helloPdu.circuitType() == IsisRouterType.L1L2.value()) {
597 isValid = true;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530598 }
599
600 return isValid;
601 }
602
603 /**
604 * Checks neighbor presents in the list or not.
605 *
606 * @param neighborMac neighbor MAc address
607 * @return true if neighbor exist else false
608 */
sunish vk4b5ce002016-05-09 20:18:35 +0530609
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530610 private boolean isNeighborInList(MacAddress neighborMac) {
611 return neighborList.containsKey(neighborMac);
612 }
613
614 /**
615 * Adds neighbor in the list.
616 *
617 * @param neighbor neighbor MAC address
618 * @return true if neighbor exist else false
619 */
620 private void addNeighbouringRouter(IsisNeighbor neighbor) {
621 neighborList.put(neighbor.neighborMacAddress(), neighbor);
622 }
623
624 /**
625 * Returns neighbor presents in the list.
626 *
627 * @param neighborMac neighbor MAc address
628 * @return neighbor instance
629 */
630 private IsisNeighbor neighbouringRouter(MacAddress neighborMac) {
631 return neighborList.get(neighborMac);
632 }
633
634 /**
635 * Processes the L1 or L2 hello message.
636 *
637 * @param isisMessage hello message instance
638 * @param channel channel instance
639 */
640 public void processL1L2HelloPduMessage(IsisMessage isisMessage, Channel channel) {
641 log.debug("Enters processL1L2HelloPduMessage ...!!!");
642 log.debug("IsisInterfaceImpl::processHelloMessage...!!!");
643
644 L1L2HelloPdu helloPacket = (L1L2HelloPdu) isisMessage;
645 log.debug("IsisInterfaceImpl::processHelloMessage::Interface Type {} ISISInterfaceState {} ",
646 networkType, interfaceState);
647
sunish vk4b5ce002016-05-09 20:18:35 +0530648 //If validate the area, network and max address
649 if (!validateHelloMessage(helloPacket)) {
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530650 return;
651 }
652
653 //Get the neighbor
654 IsisNeighbor neighbor = neighbouringRouter(isisMessage.sourceMac());
655 //Neighbor is not in list
656 if (!isNeighborInList(isisMessage.sourceMac())) {
657 neighbor = new DefaultIsisNeighbor(helloPacket, this);
658 addNeighbouringRouter(neighbor);
659 }
660
sunish vk4b5ce002016-05-09 20:18:35 +0530661 neighbor.setHoldingTime(helloPacket.holdingTime());
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530662 neighbor.stopInactivityTimeCheck();
663 neighbor.startInactivityTimeCheck();
664
665 //Assign the DIS
666 String lanId = helloPacket.lanId();
667
668 if (IsisPduType.L1HELLOPDU == helloPacket.isisPduType()) {
sunish vk4b5ce002016-05-09 20:18:35 +0530669 buildUpdateAndSendSelfGeneratedLspIfDisChange(l1LanId, lanId, channel,
670 IsisRouterType.get(helloPacket.circuitType()));
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530671 l1LanId = lanId;
672 neighbor.setL1LanId(lanId);
673 //if a change in lanid
674 } else if (IsisPduType.L2HELLOPDU == helloPacket.isisPduType()) {
sunish vk4b5ce002016-05-09 20:18:35 +0530675 buildUpdateAndSendSelfGeneratedLspIfDisChange(l2LanId, lanId, channel,
676 IsisRouterType.get(helloPacket.circuitType()));
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530677 l2LanId = lanId;
678 neighbor.setL2LanId(lanId);
679 }
680
681 //Check in neighbors list our MAC address present
682 List<MacAddress> neighbors = helloPacket.neighborList();
sunish vk4b5ce002016-05-09 20:18:35 +0530683 if (neighbors != null) {
684 for (MacAddress macAddress : neighbors) {
685 if (interfaceMacAddress.equals(macAddress)) {
686 neighbor.setNeighborState(IsisInterfaceState.UP);
687 //Build Self LSP add in LSDB and sent it.
688 buildStoreAndSendSelfGeneratedLspIfNotExistInDb(channel,
689 IsisRouterType.get(helloPacket.circuitType()));
690 break;
691 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530692 }
693 }
694 }
695
696 /**
697 * Builds and store and send self generated LSP.
698 *
699 * @param channel netty channel instance
700 */
sunish vk4b5ce002016-05-09 20:18:35 +0530701 private void buildStoreAndSendSelfGeneratedLspIfNotExistInDb(Channel channel, IsisRouterType neighborRouterType) {
702 this.channel = channel;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530703 //Check our LSP is present in DB. else create a self LSP and store it and sent it
704 String lspKey = isisLsdb.lspKey(systemId);
705 LspWrapper wrapper = null;
706 if (reservedPacketCircuitType == IsisRouterType.L1.value()) {
707 wrapper = isisLsdb.findLsp(IsisPduType.L1LSPDU, lspKey);
708 if (wrapper == null) {
709 LsPdu lsp = new LspGenerator().getLsp(this, lspKey, IsisPduType.L1LSPDU, allConfiguredInterfaceIps);
710 isisLsdb.addLsp(lsp, true, this);
711 sendLsp(lsp, channel);
712 }
713 } else if (reservedPacketCircuitType == IsisRouterType.L2.value()) {
714 wrapper = isisLsdb.findLsp(IsisPduType.L2LSPDU, lspKey);
715 if (wrapper == null) {
716 LsPdu lsp = new LspGenerator().getLsp(this, lspKey, IsisPduType.L2LSPDU, allConfiguredInterfaceIps);
717 isisLsdb.addLsp(lsp, true, this);
718 sendLsp(lsp, channel);
719 }
720 } else if (reservedPacketCircuitType == IsisRouterType.L1L2.value()) {
sunish vk4b5ce002016-05-09 20:18:35 +0530721 if ((neighborRouterType == IsisRouterType.L1 || neighborRouterType == IsisRouterType.L1L2)) {
722
723 wrapper = isisLsdb.findLsp(IsisPduType.L1LSPDU, lspKey);
724 if (wrapper == null) {
725 LsPdu lsp = new LspGenerator().getLsp(this, lspKey, IsisPduType.L1LSPDU,
726 allConfiguredInterfaceIps);
727 isisLsdb.addLsp(lsp, true, this);
728 sendLsp(lsp, channel);
729 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530730 }
731
sunish vk4b5ce002016-05-09 20:18:35 +0530732 if ((neighborRouterType == IsisRouterType.L2 || neighborRouterType == IsisRouterType.L1L2)) {
733 wrapper = isisLsdb.findLsp(IsisPduType.L2LSPDU, lspKey);
734 if (wrapper == null) {
735 LsPdu lsp = new LspGenerator().getLsp(this, lspKey, IsisPduType.L2LSPDU,
736 allConfiguredInterfaceIps);
737 isisLsdb.addLsp(lsp, true, this);
738 sendLsp(lsp, channel);
739 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530740 }
741 }
742 }
743
744 /**
745 * Builds and update in DB and send self generated LSP.
746 *
747 * @param previousLanId previous DIS ID
748 * @param latestLanId latest DIS ID
749 * @param channel netty channel instance
750 */
751 private void buildUpdateAndSendSelfGeneratedLspIfDisChange(String previousLanId,
sunish vk4b5ce002016-05-09 20:18:35 +0530752 String latestLanId, Channel channel,
753 IsisRouterType neighborRouterType) {
754 this.channel = channel;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530755 //If DIS change then build and sent LSP
sunish vk4b5ce002016-05-09 20:18:35 +0530756 if (!previousLanId.equals(latestLanId)) {
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530757 //Create a self LSP and Update it in DB and sent it
758 String lspKey = isisLsdb.lspKey(systemId);
759 if (reservedPacketCircuitType == IsisRouterType.L1.value()) {
760 LsPdu lsp = new LspGenerator().getLsp(this, lspKey, IsisPduType.L1LSPDU, allConfiguredInterfaceIps);
761 isisLsdb.addLsp(lsp, true, this);
762 sendLsp(lsp, channel);
sunish vk4b5ce002016-05-09 20:18:35 +0530763 } else if (reservedPacketCircuitType == IsisRouterType.L2.value() &&
764 (neighborRouterType == IsisRouterType.L2 || neighborRouterType == IsisRouterType.L1L2)) {
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530765 LsPdu lsp = new LspGenerator().getLsp(this, lspKey, IsisPduType.L2LSPDU, allConfiguredInterfaceIps);
766 isisLsdb.addLsp(lsp, true, this);
767 sendLsp(lsp, channel);
768 } else if (reservedPacketCircuitType == IsisRouterType.L1L2.value()) {
769 //L1 LSPDU
sunish vk4b5ce002016-05-09 20:18:35 +0530770 if (neighborRouterType == IsisRouterType.L1 || neighborRouterType == IsisRouterType.L1L2) {
771 LsPdu lsp = new LspGenerator().getLsp(this, lspKey, IsisPduType.L1LSPDU, allConfiguredInterfaceIps);
772 isisLsdb.addLsp(lsp, true, this);
773 sendLsp(lsp, channel);
774 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530775 //L1 LSPDU
sunish vk4b5ce002016-05-09 20:18:35 +0530776 if (neighborRouterType == IsisRouterType.L2 || neighborRouterType == IsisRouterType.L1L2) {
777 LsPdu lsp = new LspGenerator().getLsp(this, lspKey, IsisPduType.L2LSPDU, allConfiguredInterfaceIps);
778 isisLsdb.addLsp(lsp, true, this);
779 sendLsp(lsp, channel);
780 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530781 }
782 }
783
784 }
785
786 /**
787 * Sends LS PDU message to channel.
788 *
789 * @param lsp LS PDU message instance
790 * @param channel channel instance
791 */
792 private void sendLsp(LsPdu lsp, Channel channel) {
793 byte[] lspBytes = lsp.asBytes();
794 lspBytes = IsisUtil.addLengthAndMarkItInReserved(lspBytes, IsisConstants.LENGTHPOSITION,
795 IsisConstants.LENGTHPOSITION + 1,
796 IsisConstants.RESERVEDPOSITION);
797 lspBytes = IsisUtil.addChecksum(lspBytes, IsisConstants.CHECKSUMPOSITION,
798 IsisConstants.CHECKSUMPOSITION + 1);
799 //write to the channel
sunish vk4b5ce002016-05-09 20:18:35 +0530800 if (channel != null && channel.isConnected() && channel.isOpen()) {
801 channel.write(IsisUtil.framePacket(lspBytes, interfaceIndex));
802 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530803 }
804
805 /**
806 * Processes P2P hello message.
807 *
808 * @param isisMessage hello message instance
809 * @param channel channel instance
810 */
811 public void processP2pHelloPduMessage(IsisMessage isisMessage, Channel channel) {
812 log.debug("Enters processP2pHelloPduMessage ...!!!");
813 P2PHelloPdu helloPacket = (P2PHelloPdu) isisMessage;
814
815 log.debug("IsisInterfaceImpl::processHelloMessage::Interface Type {} OSPFInterfaceState {} ",
816 networkType, interfaceState);
817
818 //validate the area, network and max address
819 if (!validateHelloMessage(helloPacket)) {
820 return;
821 }
822
823 IsisNeighbor neighbor = null;
824 List<IsisTlv> tlvs = ((P2PHelloPdu) isisMessage).tlvs();
825 AdjacencyStateTlv stateTlv = null;
826 for (IsisTlv tlv : tlvs) {
827 if (tlv instanceof AdjacencyStateTlv) {
828 stateTlv = (AdjacencyStateTlv) tlv;
829 break;
830 }
831 }
832
833 if (stateTlv == null) {
834 neighbor = neighbouringRouter(isisMessage.sourceMac());
835 if (neighbor == null) {
836 neighbor = new DefaultIsisNeighbor(helloPacket, this);
837 addNeighbouringRouter(neighbor);
838 }
839 neighbor.setNeighborState(IsisInterfaceState.DOWN);
sunish vk4b5ce002016-05-09 20:18:35 +0530840 buildStoreAndSendSelfGeneratedLspIfNotExistInDb(channel, IsisRouterType.get(helloPacket.circuitType()));
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530841 } else if (stateTlv.adjacencyType() == IsisInterfaceState.DOWN.value()) {
842 neighbor = neighbouringRouter(isisMessage.sourceMac());
843 if (neighbor == null) {
844 neighbor = new DefaultIsisNeighbor(helloPacket, this);
845 addNeighbouringRouter(neighbor);
846 }
847 neighbor.setLocalExtendedCircuitId(stateTlv.localCircuitId());
848 } else if (stateTlv.adjacencyType() == IsisInterfaceState.INITIAL.value()) {
849 //Neighbor already present in the list
850 neighbor = neighbouringRouter(isisMessage.sourceMac());
sunish vk4b5ce002016-05-09 20:18:35 +0530851 if (neighbor == null) {
852 neighbor = new DefaultIsisNeighbor(helloPacket, this);
853 addNeighbouringRouter(neighbor);
854 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530855 neighbor.setNeighborState(IsisInterfaceState.INITIAL);
856 neighbor.setLocalExtendedCircuitId(stateTlv.localCircuitId());
857 //interfaceState = IsisInterfaceState.UP;
858 } else if (stateTlv.adjacencyType() == IsisInterfaceState.UP.value()) {
859 //Build Self LSP add in LSDB and sent it.
860 neighbor = neighbouringRouter(isisMessage.sourceMac());
861 neighbor.setNeighborState(IsisInterfaceState.UP);
862 neighbor.setLocalExtendedCircuitId(stateTlv.localCircuitId());
sunish vk4b5ce002016-05-09 20:18:35 +0530863 buildStoreAndSendSelfGeneratedLspIfNotExistInDb(channel, IsisRouterType.get(helloPacket.circuitType()));
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530864 }
865
sunish vk4b5ce002016-05-09 20:18:35 +0530866 neighbor.setHoldingTime(helloPacket.holdingTime());
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530867 neighbor.stopInactivityTimeCheck();
868 neighbor.startInactivityTimeCheck();
869 }
870
871 /**
872 * Processes LS PDU message.
873 *
874 * @param isisMessage LS pdu message instance
875 * @param channel channel instance
876 */
877 public void processLsPduMessage(IsisMessage isisMessage, Channel channel) {
878 log.debug("Enters processLsPduMessage ...!!!");
sunish vk4b5ce002016-05-09 20:18:35 +0530879 IsisNeighbor neighbor = neighbouringRouter(isisMessage.sourceMac());
880 if (networkType == IsisNetworkType.BROADCAST && neighbor == null) {
881 return;
882 }
883
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530884 LsPdu lsPdu = (LsPdu) isisMessage;
885 LspWrapper wrapper = isisLsdb.findLsp(lsPdu.isisPduType(), lsPdu.lspId());
886 if (wrapper == null || isisLsdb.isNewerOrSameLsp(lsPdu, wrapper.lsPdu()).equalsIgnoreCase("latest")) {
sunish vk4b5ce002016-05-09 20:18:35 +0530887 if (wrapper != null) { // verify if the LSA - is your own LSA - get system ID and compare LSP
888 String lspKey = isisLsdb.lspKey(systemId);
889 if (lsPdu.lspId().equals(lspKey)) {
890 lsPdu.setSequenceNumber(lsPdu.sequenceNumber() + 1);
891 if (lsPdu.pduType() == IsisPduType.L1LSPDU.value()) {
892 // setting the ls sequence number
893 isisLsdb.setL1LspSeqNo(lsPdu.sequenceNumber());
894 } else if (lsPdu.pduType() == IsisPduType.L2LSPDU.value()) {
895 // setting the ls sequence number
896 isisLsdb.setL2LspSeqNo(lsPdu.sequenceNumber());
897 }
898 isisLsdb.addLsp(lsPdu, true, this);
899 sendLsp(lsPdu, channel);
900 } else {
901 isisLsdb.addLsp(lsPdu, false, this);
902 }
903
904
905 } else {
906 //not exist in the database or latest, then add it in database
907 isisLsdb.addLsp(lsPdu, false, this);
908 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530909 }
910
911 //If network type is P2P, acknowledge with a PSNP
912 if (networkType() == IsisNetworkType.P2P) {
913 IsisPduType psnpType = null;
914 if (IsisPduType.get(lsPdu.pduType()) == IsisPduType.L1LSPDU) {
915 psnpType = IsisPduType.L1PSNP;
916 } else if (IsisPduType.get(lsPdu.pduType()) == IsisPduType.L2LSPDU) {
917 psnpType = IsisPduType.L2PSNP;
918 }
919 IsisHeader isisHeader = new LspGenerator().getHeader(psnpType);
920 Psnp psnp = new Psnp(isisHeader);
921 psnp.setSourceId(lspKeyP2P(this.systemId));
922 TlvHeader tlvHeader = new TlvHeader();
923 tlvHeader.setTlvType(TlvType.LSPENTRY.value());
924 tlvHeader.setTlvLength(0);
925 LspEntriesTlv lspEntriesTlv = new LspEntriesTlv(tlvHeader);
926 LspEntry lspEntry = new LspEntry();
927 lspEntry.setLspChecksum(lsPdu.checkSum());
928 lspEntry.setLspId(lsPdu.lspId());
929 lspEntry.setLspSequenceNumber(lsPdu.sequenceNumber());
930 lspEntry.setRemainingTime(lsPdu.remainingLifeTime());
931 lspEntriesTlv.addLspEntry(lspEntry);
932 psnp.addTlv(lspEntriesTlv);
933
934 //write it to channel buffer.
935 byte[] psnpBytes = psnp.asBytes();
936 psnpBytes = IsisUtil.addLengthAndMarkItInReserved(psnpBytes, IsisConstants.LENGTHPOSITION,
937 IsisConstants.LENGTHPOSITION + 1,
938 IsisConstants.RESERVEDPOSITION);
939 flagValue = false;
940 //write to the channel
sunish vk4b5ce002016-05-09 20:18:35 +0530941 if (channel != null && channel.isConnected() && channel.isOpen()) {
942 channel.write(IsisUtil.framePacket(psnpBytes, interfaceIndex));
943 }
944 }
945 }
946
947 /**
948 * Processes PSN PDU message.
949 * Checks for self originated LSP entries in PSNP message and sends the missing LSP.
950 *
951 * @param isisMessage PSN PDU message instance
952 * @param channel channel instance
953 */
954 public void processPsnPduMessage(IsisMessage isisMessage, Channel channel) {
955 log.debug("Enters processPsnPduMessage ...!!!");
956 //If adjacency not formed don't process.
957 IsisNeighbor neighbor = neighbouringRouter(isisMessage.sourceMac());
958 if (networkType == IsisNetworkType.BROADCAST && neighbor == null) {
959 return;
960 }
961
962 Psnp psnPacket = (Psnp) isisMessage;
963 List<IsisTlv> isisTlvs = psnPacket.getAllTlv();
964 Iterator iterator = isisTlvs.iterator();
965 while (iterator.hasNext()) {
966 IsisTlv isisTlv = (IsisTlv) iterator.next();
967 if (isisTlv instanceof LspEntriesTlv) {
968 LspEntriesTlv lspEntriesTlv = (LspEntriesTlv) isisTlv;
969 List<LspEntry> lspEntryList = lspEntriesTlv.lspEntry();
970 Iterator lspEntryListIterator = lspEntryList.iterator();
971 while (lspEntryListIterator.hasNext()) {
972 LspEntry lspEntry = (LspEntry) lspEntryListIterator.next();
973 String lspKey = lspEntry.lspId();
974 LspWrapper lspWrapper = isisLsdb.findLsp(psnPacket.isisPduType(), lspKey);
975 if (lspWrapper != null) {
976 if (lspWrapper.isSelfOriginated()) {
977 //Sent the LSP
978 sendLsp((LsPdu) lspWrapper.lsPdu(), channel);
979 }
980 }
981 }
982 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530983 }
984 }
985
986 /**
987 * Processes CSN PDU message.
988 *
989 * @param isisMessage CSN PDU message instance
990 * @param channel channel instance
991 */
992 public void processCsnPduMessage(IsisMessage isisMessage, Channel channel) {
993 log.debug("Enters processCsnPduMessage ...!!!");
sunish vk4b5ce002016-05-09 20:18:35 +0530994 IsisNeighbor neighbor = neighbouringRouter(isisMessage.sourceMac());
995 if (networkType == IsisNetworkType.BROADCAST && neighbor == null) {
996 return;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530997 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530998
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530999 Csnp csnPacket = (Csnp) isisMessage;
sunish vk4b5ce002016-05-09 20:18:35 +05301000 IsisPduType psnPduType = (IsisPduType.L2CSNP.equals(csnPacket.isisPduType())) ?
1001 IsisPduType.L2PSNP : IsisPduType.L1PSNP;
1002 IsisPduType lsPduType = (IsisPduType.L2CSNP.equals(csnPacket.isisPduType())) ?
1003 IsisPduType.L2LSPDU : IsisPduType.L1LSPDU;
1004
tejeshwer degala3fe1ed52016-04-22 17:04:01 +05301005 List<LspEntry> lspEntryRequestList = new ArrayList<>();
1006 boolean selfOriginatedFound = false;
sunish vk4b5ce002016-05-09 20:18:35 +05301007 List<IsisTlv> isisTlvs = csnPacket.getAllTlv();
1008 Iterator iterator = isisTlvs.iterator();
1009 while (iterator.hasNext()) {
1010 IsisTlv isisTlv = (IsisTlv) iterator.next();
1011 if (isisTlv instanceof LspEntriesTlv) {
1012 LspEntriesTlv lspEntriesTlv = (LspEntriesTlv) isisTlv;
1013 List<LspEntry> lspEntryList = lspEntriesTlv.lspEntry();
1014 Iterator lspEntryListIterator = lspEntryList.iterator();
1015 while (lspEntryListIterator.hasNext()) {
1016 LspEntry lspEntry = (LspEntry) lspEntryListIterator.next();
1017 String lspKey = lspEntry.lspId();
1018 LspWrapper lspWrapper = isisLsdb.findLsp(lsPduType, lspKey);
1019 if (lspWrapper != null) {
1020 LsPdu lsPdu = (LsPdu) lspWrapper.lsPdu();
1021 if (lspWrapper.isSelfOriginated()) {
1022 selfOriginatedFound = true;
1023 if (lspEntry.lspSequenceNumber() < lsPdu.sequenceNumber()) {
1024 sendLsp(lsPdu, channel);
tejeshwer degala3fe1ed52016-04-22 17:04:01 +05301025 }
1026 } else {
sunish vk4b5ce002016-05-09 20:18:35 +05301027 if (lsPdu.sequenceNumber() < lspEntry.lspSequenceNumber()) {
1028 lspEntryRequestList.add(lspEntry);
1029 flagValue = true;
1030 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +05301031 }
sunish vk4b5ce002016-05-09 20:18:35 +05301032 } else {
1033 lspEntryRequestList.add(lspEntry);
1034 flagValue = true;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +05301035 }
1036 }
1037 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +05301038 }
sunish vk4b5ce002016-05-09 20:18:35 +05301039 if (flagValue) {
1040 sendPsnPduMessage(lspEntryRequestList, psnPduType, channel);
1041 lspEntryRequestList.clear();
1042 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +05301043
sunish vk4b5ce002016-05-09 20:18:35 +05301044 if (!selfOriginatedFound) {
1045 String lspKey = isisLsdb.lspKey(systemId);
1046 LspWrapper wrapper = isisLsdb.findLsp(lsPduType, lspKey);
1047 if (wrapper != null) {
tejeshwer degala3fe1ed52016-04-22 17:04:01 +05301048 sendLsp((LsPdu) wrapper.lsPdu(), channel);
1049 }
1050 }
1051 }
1052
1053 /**
1054 * Sends the partial sequence number PDU.
1055 *
1056 * @param lspEntryRequestList list of lsp entry request
1057 * @param isisPduType intermediate system PDU type
1058 * @param channel netty channel instance
1059 */
1060 private void sendPsnPduMessage(List<LspEntry> lspEntryRequestList, IsisPduType isisPduType, Channel channel) {
sunish vk4b5ce002016-05-09 20:18:35 +05301061 IsisHeader isisHeader = new LspGenerator().getHeader(isisPduType);
tejeshwer degala3fe1ed52016-04-22 17:04:01 +05301062 Psnp psnp = new Psnp(isisHeader);
1063 psnp.setSourceId(lspKeyP2P(this.systemId));
1064 TlvHeader tlvHeader = new TlvHeader();
1065 tlvHeader.setTlvType(TlvType.LSPENTRY.value());
1066 tlvHeader.setTlvLength(0);
1067 LspEntriesTlv lspEntriesTlv = new LspEntriesTlv(tlvHeader);
1068 for (LspEntry lspEntry : lspEntryRequestList) {
sunish vk4b5ce002016-05-09 20:18:35 +05301069 lspEntry.setLspChecksum(0);
1070 lspEntry.setLspSequenceNumber(0);
1071 lspEntry.setRemainingTime(0);
tejeshwer degala3fe1ed52016-04-22 17:04:01 +05301072 lspEntriesTlv.addLspEntry(lspEntry);
1073 }
1074 psnp.addTlv(lspEntriesTlv);
1075 //write it to channel buffer.
1076 byte[] psnpBytes = psnp.asBytes();
1077 psnpBytes = IsisUtil.addLengthAndMarkItInReserved(psnpBytes, IsisConstants.LENGTHPOSITION,
1078 IsisConstants.LENGTHPOSITION + 1,
1079 IsisConstants.RESERVEDPOSITION);
1080 flagValue = false;
1081 //write to the channel
sunish vk4b5ce002016-05-09 20:18:35 +05301082 if (channel != null && channel.isConnected() && channel.isOpen()) {
1083 channel.write(IsisUtil.framePacket(psnpBytes, interfaceIndex));
1084 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +05301085 }
1086
1087 /**
1088 * Gets the LSP key.
1089 *
1090 * @param systemId system ID
1091 * @return key
1092 */
1093 public String lspKeyP2P(String systemId) {
1094 StringBuilder lspKey = new StringBuilder();
1095 lspKey.append(systemId);
1096 lspKey.append(".00");
1097 return lspKey.toString();
1098 }
1099
1100 /**
tejeshwer degala3fe1ed52016-04-22 17:04:01 +05301101 * Starts the hello timer which sends hello packet every configured seconds.
1102 *
1103 * @param channel netty channel instance
1104 */
1105 public void startHelloSender(Channel channel) {
1106 log.debug("IsisInterfaceImpl::startHelloSender");
sunish vkc3824e82016-05-11 19:38:24 +05301107 if (!helloSenderStarted) {
1108 isisHelloPduSender = new IsisHelloPduSender(channel, this);
1109 exServiceHello = Executors.newSingleThreadScheduledExecutor();
1110 final ScheduledFuture<?> helloHandle =
1111 exServiceHello.scheduleAtFixedRate(isisHelloPduSender, 0,
1112 helloInterval, TimeUnit.SECONDS);
1113 helloSenderStarted = true;
1114 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +05301115 }
sunish vk4b5ce002016-05-09 20:18:35 +05301116
1117 /**
1118 * Stops the hello timer which sends hello packet every configured seconds.
1119 */
1120 public void stopHelloSender() {
1121 log.debug("IsisInterfaceImpl::stopHelloSender");
1122 exServiceHello.shutdown();
sunish vkc3824e82016-05-11 19:38:24 +05301123 helloSenderStarted = false;
sunish vk4b5ce002016-05-09 20:18:35 +05301124 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +05301125}