blob: 49bfd74ae97d37dbfd79d50e62dd204ed831adb9 [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
Ray Milkey0bb1e102016-11-10 14:51:27 -0800515 * @param channel channel
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530516 */
517 public void processIsisMessage(IsisMessage isisMessage, IsisLsdb isisLsdb, Channel channel) {
518 log.debug("IsisInterfaceImpl::processIsisMessage...!!!");
sunish vk4b5ce002016-05-09 20:18:35 +0530519 this.channel = channel;
520
521 if (isisMessage.sourceMac().equals(interfaceMacAddress)) {
522 log.debug("Received our own message {}...!!!", isisMessage.isisPduType());
523 return;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530524 }
sunish vk4b5ce002016-05-09 20:18:35 +0530525
526 if (isisMessage.isisPduType() == IsisPduType.P2PHELLOPDU && networkType.equals(IsisNetworkType.BROADCAST)) {
527 return;
528 } else if ((isisMessage.isisPduType() == IsisPduType.L1HELLOPDU ||
529 isisMessage.isisPduType() == IsisPduType.L2HELLOPDU)
530 && networkType.equals(IsisNetworkType.P2P)) {
531 return;
532 }
533
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530534 if (this.isisLsdb == null) {
535 this.isisLsdb = isisLsdb;
536 }
537
538 switch (isisMessage.isisPduType()) {
539 case L1HELLOPDU:
540 case L2HELLOPDU:
541 processL1L2HelloPduMessage(isisMessage, channel);
542 break;
543 case P2PHELLOPDU:
544 processP2pHelloPduMessage(isisMessage, channel);
545 break;
546 case L1LSPDU:
547 case L2LSPDU:
548 processLsPduMessage(isisMessage, channel);
549 break;
550 case L1CSNP:
551 case L2CSNP:
552 processCsnPduMessage(isisMessage, channel);
553 break;
554 case L1PSNP:
555 case L2PSNP:
sunish vk4b5ce002016-05-09 20:18:35 +0530556 processPsnPduMessage(isisMessage, channel);
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530557 break;
558 default:
559 log.debug("Unknown packet to process...!!!");
560 break;
561 }
562 }
563
564 /**
565 * Validates the received message.
566 *
567 * @param helloPdu ISIS message instance
568 * @return true if valid ISIS message else false
569 */
570 public boolean validateHelloMessage(HelloPdu helloPdu) {
571 boolean isValid = false;
572
sunish vk4b5ce002016-05-09 20:18:35 +0530573 if ((helloPdu.circuitType() == IsisRouterType.L1.value() &&
574 reservedPacketCircuitType == IsisRouterType.L2.value()) ||
575 (helloPdu.circuitType() == IsisRouterType.L2.value() &&
576 reservedPacketCircuitType == IsisRouterType.L1.value())) {
577 return false;
578 }
579
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530580 //Local InterfaceAddress TLV and compare with the IP Interface address and check if they are in same subnet
581 List<Ip4Address> interfaceIpAddresses = helloPdu.interfaceIpAddresses();
582 Ip4Address neighborIp = (helloPdu.interfaceIpAddresses() != null) ?
583 interfaceIpAddresses.get(0) : Ip4Address.valueOf("0.0.0.0");
584 if (!IsisUtil.sameNetwork(interfaceIpAddress, neighborIp, networkMask)) {
585 return false;
586 }
587
588 //Verify if it's in same area, Areas which the router belongs to
sunish vk4b5ce002016-05-09 20:18:35 +0530589 if (helloPdu.circuitType() == IsisRouterType.L1.value()) {
590 List<String> areas = helloPdu.areaAddress();
591 for (String area : areas) {
592 if (areaAddress.equals(area)) {
593 isValid = true;
594 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530595 }
sunish vk4b5ce002016-05-09 20:18:35 +0530596 } else if (helloPdu.circuitType() == IsisRouterType.L2.value() ||
597 helloPdu.circuitType() == IsisRouterType.L1L2.value()) {
598 isValid = true;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530599 }
600
601 return isValid;
602 }
603
604 /**
605 * Checks neighbor presents in the list or not.
606 *
607 * @param neighborMac neighbor MAc address
608 * @return true if neighbor exist else false
609 */
sunish vk4b5ce002016-05-09 20:18:35 +0530610
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530611 private boolean isNeighborInList(MacAddress neighborMac) {
612 return neighborList.containsKey(neighborMac);
613 }
614
615 /**
616 * Adds neighbor in the list.
617 *
618 * @param neighbor neighbor MAC address
619 * @return true if neighbor exist else false
620 */
621 private void addNeighbouringRouter(IsisNeighbor neighbor) {
622 neighborList.put(neighbor.neighborMacAddress(), neighbor);
623 }
624
625 /**
626 * Returns neighbor presents in the list.
627 *
628 * @param neighborMac neighbor MAc address
629 * @return neighbor instance
630 */
631 private IsisNeighbor neighbouringRouter(MacAddress neighborMac) {
632 return neighborList.get(neighborMac);
633 }
634
635 /**
636 * Processes the L1 or L2 hello message.
637 *
638 * @param isisMessage hello message instance
639 * @param channel channel instance
640 */
641 public void processL1L2HelloPduMessage(IsisMessage isisMessage, Channel channel) {
642 log.debug("Enters processL1L2HelloPduMessage ...!!!");
643 log.debug("IsisInterfaceImpl::processHelloMessage...!!!");
644
645 L1L2HelloPdu helloPacket = (L1L2HelloPdu) isisMessage;
646 log.debug("IsisInterfaceImpl::processHelloMessage::Interface Type {} ISISInterfaceState {} ",
647 networkType, interfaceState);
648
sunish vk4b5ce002016-05-09 20:18:35 +0530649 //If validate the area, network and max address
650 if (!validateHelloMessage(helloPacket)) {
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530651 return;
652 }
653
654 //Get the neighbor
655 IsisNeighbor neighbor = neighbouringRouter(isisMessage.sourceMac());
656 //Neighbor is not in list
657 if (!isNeighborInList(isisMessage.sourceMac())) {
658 neighbor = new DefaultIsisNeighbor(helloPacket, this);
659 addNeighbouringRouter(neighbor);
660 }
661
sunish vk4b5ce002016-05-09 20:18:35 +0530662 neighbor.setHoldingTime(helloPacket.holdingTime());
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530663 neighbor.stopInactivityTimeCheck();
664 neighbor.startInactivityTimeCheck();
665
666 //Assign the DIS
667 String lanId = helloPacket.lanId();
668
669 if (IsisPduType.L1HELLOPDU == helloPacket.isisPduType()) {
sunish vk4b5ce002016-05-09 20:18:35 +0530670 buildUpdateAndSendSelfGeneratedLspIfDisChange(l1LanId, lanId, channel,
671 IsisRouterType.get(helloPacket.circuitType()));
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530672 l1LanId = lanId;
673 neighbor.setL1LanId(lanId);
674 //if a change in lanid
675 } else if (IsisPduType.L2HELLOPDU == helloPacket.isisPduType()) {
sunish vk4b5ce002016-05-09 20:18:35 +0530676 buildUpdateAndSendSelfGeneratedLspIfDisChange(l2LanId, lanId, channel,
677 IsisRouterType.get(helloPacket.circuitType()));
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530678 l2LanId = lanId;
679 neighbor.setL2LanId(lanId);
680 }
681
682 //Check in neighbors list our MAC address present
683 List<MacAddress> neighbors = helloPacket.neighborList();
sunish vk4b5ce002016-05-09 20:18:35 +0530684 if (neighbors != null) {
685 for (MacAddress macAddress : neighbors) {
686 if (interfaceMacAddress.equals(macAddress)) {
687 neighbor.setNeighborState(IsisInterfaceState.UP);
688 //Build Self LSP add in LSDB and sent it.
689 buildStoreAndSendSelfGeneratedLspIfNotExistInDb(channel,
690 IsisRouterType.get(helloPacket.circuitType()));
691 break;
692 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530693 }
694 }
695 }
696
697 /**
698 * Builds and store and send self generated LSP.
699 *
700 * @param channel netty channel instance
701 */
sunish vk4b5ce002016-05-09 20:18:35 +0530702 private void buildStoreAndSendSelfGeneratedLspIfNotExistInDb(Channel channel, IsisRouterType neighborRouterType) {
703 this.channel = channel;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530704 //Check our LSP is present in DB. else create a self LSP and store it and sent it
705 String lspKey = isisLsdb.lspKey(systemId);
706 LspWrapper wrapper = null;
707 if (reservedPacketCircuitType == IsisRouterType.L1.value()) {
708 wrapper = isisLsdb.findLsp(IsisPduType.L1LSPDU, lspKey);
709 if (wrapper == null) {
710 LsPdu lsp = new LspGenerator().getLsp(this, lspKey, IsisPduType.L1LSPDU, allConfiguredInterfaceIps);
711 isisLsdb.addLsp(lsp, true, this);
712 sendLsp(lsp, channel);
713 }
714 } else if (reservedPacketCircuitType == IsisRouterType.L2.value()) {
715 wrapper = isisLsdb.findLsp(IsisPduType.L2LSPDU, lspKey);
716 if (wrapper == null) {
717 LsPdu lsp = new LspGenerator().getLsp(this, lspKey, IsisPduType.L2LSPDU, allConfiguredInterfaceIps);
718 isisLsdb.addLsp(lsp, true, this);
719 sendLsp(lsp, channel);
720 }
721 } else if (reservedPacketCircuitType == IsisRouterType.L1L2.value()) {
sunish vk4b5ce002016-05-09 20:18:35 +0530722 if ((neighborRouterType == IsisRouterType.L1 || neighborRouterType == IsisRouterType.L1L2)) {
723
724 wrapper = isisLsdb.findLsp(IsisPduType.L1LSPDU, lspKey);
725 if (wrapper == null) {
726 LsPdu lsp = new LspGenerator().getLsp(this, lspKey, IsisPduType.L1LSPDU,
727 allConfiguredInterfaceIps);
728 isisLsdb.addLsp(lsp, true, this);
729 sendLsp(lsp, channel);
730 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530731 }
732
sunish vk4b5ce002016-05-09 20:18:35 +0530733 if ((neighborRouterType == IsisRouterType.L2 || neighborRouterType == IsisRouterType.L1L2)) {
734 wrapper = isisLsdb.findLsp(IsisPduType.L2LSPDU, lspKey);
735 if (wrapper == null) {
736 LsPdu lsp = new LspGenerator().getLsp(this, lspKey, IsisPduType.L2LSPDU,
737 allConfiguredInterfaceIps);
738 isisLsdb.addLsp(lsp, true, this);
739 sendLsp(lsp, channel);
740 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530741 }
742 }
743 }
744
745 /**
746 * Builds and update in DB and send self generated LSP.
747 *
748 * @param previousLanId previous DIS ID
749 * @param latestLanId latest DIS ID
750 * @param channel netty channel instance
751 */
752 private void buildUpdateAndSendSelfGeneratedLspIfDisChange(String previousLanId,
sunish vk4b5ce002016-05-09 20:18:35 +0530753 String latestLanId, Channel channel,
754 IsisRouterType neighborRouterType) {
755 this.channel = channel;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530756 //If DIS change then build and sent LSP
sunish vk4b5ce002016-05-09 20:18:35 +0530757 if (!previousLanId.equals(latestLanId)) {
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530758 //Create a self LSP and Update it in DB and sent it
759 String lspKey = isisLsdb.lspKey(systemId);
760 if (reservedPacketCircuitType == IsisRouterType.L1.value()) {
761 LsPdu lsp = new LspGenerator().getLsp(this, lspKey, IsisPduType.L1LSPDU, allConfiguredInterfaceIps);
762 isisLsdb.addLsp(lsp, true, this);
763 sendLsp(lsp, channel);
sunish vk4b5ce002016-05-09 20:18:35 +0530764 } else if (reservedPacketCircuitType == IsisRouterType.L2.value() &&
765 (neighborRouterType == IsisRouterType.L2 || neighborRouterType == IsisRouterType.L1L2)) {
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530766 LsPdu lsp = new LspGenerator().getLsp(this, lspKey, IsisPduType.L2LSPDU, allConfiguredInterfaceIps);
767 isisLsdb.addLsp(lsp, true, this);
768 sendLsp(lsp, channel);
769 } else if (reservedPacketCircuitType == IsisRouterType.L1L2.value()) {
770 //L1 LSPDU
sunish vk4b5ce002016-05-09 20:18:35 +0530771 if (neighborRouterType == IsisRouterType.L1 || neighborRouterType == IsisRouterType.L1L2) {
772 LsPdu lsp = new LspGenerator().getLsp(this, lspKey, IsisPduType.L1LSPDU, allConfiguredInterfaceIps);
773 isisLsdb.addLsp(lsp, true, this);
774 sendLsp(lsp, channel);
775 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530776 //L1 LSPDU
sunish vk4b5ce002016-05-09 20:18:35 +0530777 if (neighborRouterType == IsisRouterType.L2 || neighborRouterType == IsisRouterType.L1L2) {
778 LsPdu lsp = new LspGenerator().getLsp(this, lspKey, IsisPduType.L2LSPDU, allConfiguredInterfaceIps);
779 isisLsdb.addLsp(lsp, true, this);
780 sendLsp(lsp, channel);
781 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530782 }
783 }
784
785 }
786
787 /**
788 * Sends LS PDU message to channel.
789 *
790 * @param lsp LS PDU message instance
791 * @param channel channel instance
792 */
793 private void sendLsp(LsPdu lsp, Channel channel) {
794 byte[] lspBytes = lsp.asBytes();
795 lspBytes = IsisUtil.addLengthAndMarkItInReserved(lspBytes, IsisConstants.LENGTHPOSITION,
796 IsisConstants.LENGTHPOSITION + 1,
797 IsisConstants.RESERVEDPOSITION);
798 lspBytes = IsisUtil.addChecksum(lspBytes, IsisConstants.CHECKSUMPOSITION,
799 IsisConstants.CHECKSUMPOSITION + 1);
800 //write to the channel
sunish vk4b5ce002016-05-09 20:18:35 +0530801 if (channel != null && channel.isConnected() && channel.isOpen()) {
802 channel.write(IsisUtil.framePacket(lspBytes, interfaceIndex));
803 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530804 }
805
806 /**
807 * Processes P2P hello message.
808 *
809 * @param isisMessage hello message instance
810 * @param channel channel instance
811 */
812 public void processP2pHelloPduMessage(IsisMessage isisMessage, Channel channel) {
813 log.debug("Enters processP2pHelloPduMessage ...!!!");
814 P2PHelloPdu helloPacket = (P2PHelloPdu) isisMessage;
815
816 log.debug("IsisInterfaceImpl::processHelloMessage::Interface Type {} OSPFInterfaceState {} ",
817 networkType, interfaceState);
818
819 //validate the area, network and max address
820 if (!validateHelloMessage(helloPacket)) {
821 return;
822 }
823
824 IsisNeighbor neighbor = null;
825 List<IsisTlv> tlvs = ((P2PHelloPdu) isisMessage).tlvs();
826 AdjacencyStateTlv stateTlv = null;
827 for (IsisTlv tlv : tlvs) {
828 if (tlv instanceof AdjacencyStateTlv) {
829 stateTlv = (AdjacencyStateTlv) tlv;
830 break;
831 }
832 }
833
834 if (stateTlv == null) {
835 neighbor = neighbouringRouter(isisMessage.sourceMac());
836 if (neighbor == null) {
837 neighbor = new DefaultIsisNeighbor(helloPacket, this);
838 addNeighbouringRouter(neighbor);
839 }
840 neighbor.setNeighborState(IsisInterfaceState.DOWN);
sunish vk4b5ce002016-05-09 20:18:35 +0530841 buildStoreAndSendSelfGeneratedLspIfNotExistInDb(channel, IsisRouterType.get(helloPacket.circuitType()));
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530842 } else if (stateTlv.adjacencyType() == IsisInterfaceState.DOWN.value()) {
843 neighbor = neighbouringRouter(isisMessage.sourceMac());
844 if (neighbor == null) {
845 neighbor = new DefaultIsisNeighbor(helloPacket, this);
846 addNeighbouringRouter(neighbor);
847 }
848 neighbor.setLocalExtendedCircuitId(stateTlv.localCircuitId());
849 } else if (stateTlv.adjacencyType() == IsisInterfaceState.INITIAL.value()) {
850 //Neighbor already present in the list
851 neighbor = neighbouringRouter(isisMessage.sourceMac());
sunish vk4b5ce002016-05-09 20:18:35 +0530852 if (neighbor == null) {
853 neighbor = new DefaultIsisNeighbor(helloPacket, this);
854 addNeighbouringRouter(neighbor);
855 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530856 neighbor.setNeighborState(IsisInterfaceState.INITIAL);
857 neighbor.setLocalExtendedCircuitId(stateTlv.localCircuitId());
858 //interfaceState = IsisInterfaceState.UP;
859 } else if (stateTlv.adjacencyType() == IsisInterfaceState.UP.value()) {
860 //Build Self LSP add in LSDB and sent it.
861 neighbor = neighbouringRouter(isisMessage.sourceMac());
862 neighbor.setNeighborState(IsisInterfaceState.UP);
863 neighbor.setLocalExtendedCircuitId(stateTlv.localCircuitId());
sunish vk4b5ce002016-05-09 20:18:35 +0530864 buildStoreAndSendSelfGeneratedLspIfNotExistInDb(channel, IsisRouterType.get(helloPacket.circuitType()));
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530865 }
866
sunish vk4b5ce002016-05-09 20:18:35 +0530867 neighbor.setHoldingTime(helloPacket.holdingTime());
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530868 neighbor.stopInactivityTimeCheck();
869 neighbor.startInactivityTimeCheck();
870 }
871
872 /**
873 * Processes LS PDU message.
874 *
875 * @param isisMessage LS pdu message instance
876 * @param channel channel instance
877 */
878 public void processLsPduMessage(IsisMessage isisMessage, Channel channel) {
879 log.debug("Enters processLsPduMessage ...!!!");
sunish vk4b5ce002016-05-09 20:18:35 +0530880 IsisNeighbor neighbor = neighbouringRouter(isisMessage.sourceMac());
881 if (networkType == IsisNetworkType.BROADCAST && neighbor == null) {
882 return;
883 }
884
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530885 LsPdu lsPdu = (LsPdu) isisMessage;
886 LspWrapper wrapper = isisLsdb.findLsp(lsPdu.isisPduType(), lsPdu.lspId());
887 if (wrapper == null || isisLsdb.isNewerOrSameLsp(lsPdu, wrapper.lsPdu()).equalsIgnoreCase("latest")) {
sunish vk4b5ce002016-05-09 20:18:35 +0530888 if (wrapper != null) { // verify if the LSA - is your own LSA - get system ID and compare LSP
889 String lspKey = isisLsdb.lspKey(systemId);
890 if (lsPdu.lspId().equals(lspKey)) {
891 lsPdu.setSequenceNumber(lsPdu.sequenceNumber() + 1);
892 if (lsPdu.pduType() == IsisPduType.L1LSPDU.value()) {
893 // setting the ls sequence number
894 isisLsdb.setL1LspSeqNo(lsPdu.sequenceNumber());
895 } else if (lsPdu.pduType() == IsisPduType.L2LSPDU.value()) {
896 // setting the ls sequence number
897 isisLsdb.setL2LspSeqNo(lsPdu.sequenceNumber());
898 }
899 isisLsdb.addLsp(lsPdu, true, this);
900 sendLsp(lsPdu, channel);
901 } else {
902 isisLsdb.addLsp(lsPdu, false, this);
903 }
904
905
906 } else {
907 //not exist in the database or latest, then add it in database
908 isisLsdb.addLsp(lsPdu, false, this);
909 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530910 }
911
912 //If network type is P2P, acknowledge with a PSNP
913 if (networkType() == IsisNetworkType.P2P) {
914 IsisPduType psnpType = null;
915 if (IsisPduType.get(lsPdu.pduType()) == IsisPduType.L1LSPDU) {
916 psnpType = IsisPduType.L1PSNP;
917 } else if (IsisPduType.get(lsPdu.pduType()) == IsisPduType.L2LSPDU) {
918 psnpType = IsisPduType.L2PSNP;
919 }
920 IsisHeader isisHeader = new LspGenerator().getHeader(psnpType);
921 Psnp psnp = new Psnp(isisHeader);
922 psnp.setSourceId(lspKeyP2P(this.systemId));
923 TlvHeader tlvHeader = new TlvHeader();
924 tlvHeader.setTlvType(TlvType.LSPENTRY.value());
925 tlvHeader.setTlvLength(0);
926 LspEntriesTlv lspEntriesTlv = new LspEntriesTlv(tlvHeader);
927 LspEntry lspEntry = new LspEntry();
928 lspEntry.setLspChecksum(lsPdu.checkSum());
929 lspEntry.setLspId(lsPdu.lspId());
930 lspEntry.setLspSequenceNumber(lsPdu.sequenceNumber());
931 lspEntry.setRemainingTime(lsPdu.remainingLifeTime());
932 lspEntriesTlv.addLspEntry(lspEntry);
933 psnp.addTlv(lspEntriesTlv);
934
935 //write it to channel buffer.
936 byte[] psnpBytes = psnp.asBytes();
937 psnpBytes = IsisUtil.addLengthAndMarkItInReserved(psnpBytes, IsisConstants.LENGTHPOSITION,
938 IsisConstants.LENGTHPOSITION + 1,
939 IsisConstants.RESERVEDPOSITION);
940 flagValue = false;
941 //write to the channel
sunish vk4b5ce002016-05-09 20:18:35 +0530942 if (channel != null && channel.isConnected() && channel.isOpen()) {
943 channel.write(IsisUtil.framePacket(psnpBytes, interfaceIndex));
944 }
945 }
946 }
947
948 /**
949 * Processes PSN PDU message.
950 * Checks for self originated LSP entries in PSNP message and sends the missing LSP.
951 *
952 * @param isisMessage PSN PDU message instance
953 * @param channel channel instance
954 */
955 public void processPsnPduMessage(IsisMessage isisMessage, Channel channel) {
956 log.debug("Enters processPsnPduMessage ...!!!");
957 //If adjacency not formed don't process.
958 IsisNeighbor neighbor = neighbouringRouter(isisMessage.sourceMac());
959 if (networkType == IsisNetworkType.BROADCAST && neighbor == null) {
960 return;
961 }
962
963 Psnp psnPacket = (Psnp) isisMessage;
964 List<IsisTlv> isisTlvs = psnPacket.getAllTlv();
965 Iterator iterator = isisTlvs.iterator();
966 while (iterator.hasNext()) {
967 IsisTlv isisTlv = (IsisTlv) iterator.next();
968 if (isisTlv instanceof LspEntriesTlv) {
969 LspEntriesTlv lspEntriesTlv = (LspEntriesTlv) isisTlv;
970 List<LspEntry> lspEntryList = lspEntriesTlv.lspEntry();
971 Iterator lspEntryListIterator = lspEntryList.iterator();
972 while (lspEntryListIterator.hasNext()) {
973 LspEntry lspEntry = (LspEntry) lspEntryListIterator.next();
974 String lspKey = lspEntry.lspId();
975 LspWrapper lspWrapper = isisLsdb.findLsp(psnPacket.isisPduType(), lspKey);
976 if (lspWrapper != null) {
977 if (lspWrapper.isSelfOriginated()) {
978 //Sent the LSP
979 sendLsp((LsPdu) lspWrapper.lsPdu(), channel);
980 }
981 }
982 }
983 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530984 }
985 }
986
987 /**
988 * Processes CSN PDU message.
989 *
990 * @param isisMessage CSN PDU message instance
991 * @param channel channel instance
992 */
993 public void processCsnPduMessage(IsisMessage isisMessage, Channel channel) {
994 log.debug("Enters processCsnPduMessage ...!!!");
sunish vk4b5ce002016-05-09 20:18:35 +0530995 IsisNeighbor neighbor = neighbouringRouter(isisMessage.sourceMac());
996 if (networkType == IsisNetworkType.BROADCAST && neighbor == null) {
997 return;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530998 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530999
tejeshwer degala3fe1ed52016-04-22 17:04:01 +05301000 Csnp csnPacket = (Csnp) isisMessage;
sunish vk4b5ce002016-05-09 20:18:35 +05301001 IsisPduType psnPduType = (IsisPduType.L2CSNP.equals(csnPacket.isisPduType())) ?
1002 IsisPduType.L2PSNP : IsisPduType.L1PSNP;
1003 IsisPduType lsPduType = (IsisPduType.L2CSNP.equals(csnPacket.isisPduType())) ?
1004 IsisPduType.L2LSPDU : IsisPduType.L1LSPDU;
1005
tejeshwer degala3fe1ed52016-04-22 17:04:01 +05301006 List<LspEntry> lspEntryRequestList = new ArrayList<>();
1007 boolean selfOriginatedFound = false;
sunish vk4b5ce002016-05-09 20:18:35 +05301008 List<IsisTlv> isisTlvs = csnPacket.getAllTlv();
1009 Iterator iterator = isisTlvs.iterator();
1010 while (iterator.hasNext()) {
1011 IsisTlv isisTlv = (IsisTlv) iterator.next();
1012 if (isisTlv instanceof LspEntriesTlv) {
1013 LspEntriesTlv lspEntriesTlv = (LspEntriesTlv) isisTlv;
1014 List<LspEntry> lspEntryList = lspEntriesTlv.lspEntry();
1015 Iterator lspEntryListIterator = lspEntryList.iterator();
1016 while (lspEntryListIterator.hasNext()) {
1017 LspEntry lspEntry = (LspEntry) lspEntryListIterator.next();
1018 String lspKey = lspEntry.lspId();
1019 LspWrapper lspWrapper = isisLsdb.findLsp(lsPduType, lspKey);
1020 if (lspWrapper != null) {
1021 LsPdu lsPdu = (LsPdu) lspWrapper.lsPdu();
1022 if (lspWrapper.isSelfOriginated()) {
1023 selfOriginatedFound = true;
1024 if (lspEntry.lspSequenceNumber() < lsPdu.sequenceNumber()) {
1025 sendLsp(lsPdu, channel);
tejeshwer degala3fe1ed52016-04-22 17:04:01 +05301026 }
1027 } else {
sunish vk4b5ce002016-05-09 20:18:35 +05301028 if (lsPdu.sequenceNumber() < lspEntry.lspSequenceNumber()) {
1029 lspEntryRequestList.add(lspEntry);
1030 flagValue = true;
1031 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +05301032 }
sunish vk4b5ce002016-05-09 20:18:35 +05301033 } else {
1034 lspEntryRequestList.add(lspEntry);
1035 flagValue = true;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +05301036 }
1037 }
1038 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +05301039 }
sunish vk4b5ce002016-05-09 20:18:35 +05301040 if (flagValue) {
1041 sendPsnPduMessage(lspEntryRequestList, psnPduType, channel);
1042 lspEntryRequestList.clear();
1043 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +05301044
sunish vk4b5ce002016-05-09 20:18:35 +05301045 if (!selfOriginatedFound) {
1046 String lspKey = isisLsdb.lspKey(systemId);
1047 LspWrapper wrapper = isisLsdb.findLsp(lsPduType, lspKey);
1048 if (wrapper != null) {
tejeshwer degala3fe1ed52016-04-22 17:04:01 +05301049 sendLsp((LsPdu) wrapper.lsPdu(), channel);
1050 }
1051 }
1052 }
1053
1054 /**
1055 * Sends the partial sequence number PDU.
1056 *
1057 * @param lspEntryRequestList list of lsp entry request
1058 * @param isisPduType intermediate system PDU type
1059 * @param channel netty channel instance
1060 */
1061 private void sendPsnPduMessage(List<LspEntry> lspEntryRequestList, IsisPduType isisPduType, Channel channel) {
sunish vk4b5ce002016-05-09 20:18:35 +05301062 IsisHeader isisHeader = new LspGenerator().getHeader(isisPduType);
tejeshwer degala3fe1ed52016-04-22 17:04:01 +05301063 Psnp psnp = new Psnp(isisHeader);
1064 psnp.setSourceId(lspKeyP2P(this.systemId));
1065 TlvHeader tlvHeader = new TlvHeader();
1066 tlvHeader.setTlvType(TlvType.LSPENTRY.value());
1067 tlvHeader.setTlvLength(0);
1068 LspEntriesTlv lspEntriesTlv = new LspEntriesTlv(tlvHeader);
1069 for (LspEntry lspEntry : lspEntryRequestList) {
sunish vk4b5ce002016-05-09 20:18:35 +05301070 lspEntry.setLspChecksum(0);
1071 lspEntry.setLspSequenceNumber(0);
1072 lspEntry.setRemainingTime(0);
tejeshwer degala3fe1ed52016-04-22 17:04:01 +05301073 lspEntriesTlv.addLspEntry(lspEntry);
1074 }
1075 psnp.addTlv(lspEntriesTlv);
1076 //write it to channel buffer.
1077 byte[] psnpBytes = psnp.asBytes();
1078 psnpBytes = IsisUtil.addLengthAndMarkItInReserved(psnpBytes, IsisConstants.LENGTHPOSITION,
1079 IsisConstants.LENGTHPOSITION + 1,
1080 IsisConstants.RESERVEDPOSITION);
1081 flagValue = false;
1082 //write to the channel
sunish vk4b5ce002016-05-09 20:18:35 +05301083 if (channel != null && channel.isConnected() && channel.isOpen()) {
1084 channel.write(IsisUtil.framePacket(psnpBytes, interfaceIndex));
1085 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +05301086 }
1087
1088 /**
1089 * Gets the LSP key.
1090 *
1091 * @param systemId system ID
1092 * @return key
1093 */
1094 public String lspKeyP2P(String systemId) {
1095 StringBuilder lspKey = new StringBuilder();
1096 lspKey.append(systemId);
1097 lspKey.append(".00");
1098 return lspKey.toString();
1099 }
1100
1101 /**
tejeshwer degala3fe1ed52016-04-22 17:04:01 +05301102 * Starts the hello timer which sends hello packet every configured seconds.
1103 *
1104 * @param channel netty channel instance
1105 */
1106 public void startHelloSender(Channel channel) {
1107 log.debug("IsisInterfaceImpl::startHelloSender");
sunish vkc3824e82016-05-11 19:38:24 +05301108 if (!helloSenderStarted) {
1109 isisHelloPduSender = new IsisHelloPduSender(channel, this);
1110 exServiceHello = Executors.newSingleThreadScheduledExecutor();
1111 final ScheduledFuture<?> helloHandle =
1112 exServiceHello.scheduleAtFixedRate(isisHelloPduSender, 0,
1113 helloInterval, TimeUnit.SECONDS);
1114 helloSenderStarted = true;
1115 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +05301116 }
sunish vk4b5ce002016-05-09 20:18:35 +05301117
1118 /**
1119 * Stops the hello timer which sends hello packet every configured seconds.
1120 */
1121 public void stopHelloSender() {
1122 log.debug("IsisInterfaceImpl::stopHelloSender");
1123 exServiceHello.shutdown();
sunish vkc3824e82016-05-11 19:38:24 +05301124 helloSenderStarted = false;
sunish vk4b5ce002016-05-09 20:18:35 +05301125 }
Ray Milkey0bb1e102016-11-10 14:51:27 -08001126}