blob: 0d284bf2e3638849a3fe3250477be0df98bf6313 [file] [log] [blame]
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301/*
2* Copyright 2016 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.ospf.controller.impl;
17
18import org.jboss.netty.channel.Channel;
19import org.onlab.packet.Ip4Address;
20import org.onlab.util.Bandwidth;
21import org.onosproject.ospf.controller.DeviceInformation;
22import org.onosproject.ospf.controller.LinkInformation;
23import org.onosproject.ospf.controller.LsaWrapper;
24import org.onosproject.ospf.controller.OspfArea;
25import org.onosproject.ospf.controller.OspfDeviceTed;
26import org.onosproject.ospf.controller.OspfInterface;
27import org.onosproject.ospf.controller.OspfLinkTed;
28import org.onosproject.ospf.controller.OspfLsa;
29import org.onosproject.ospf.controller.OspfLsaType;
30import org.onosproject.ospf.controller.OspfLsdb;
31import org.onosproject.ospf.controller.OspfNbr;
32import org.onosproject.ospf.controller.OspfNeighborState;
33import org.onosproject.ospf.controller.OspfRouter;
34import org.onosproject.ospf.controller.TopologyForDeviceAndLink;
35import org.onosproject.ospf.controller.area.OspfAreaImpl;
36import org.onosproject.ospf.controller.area.OspfInterfaceImpl;
37import org.onosproject.ospf.controller.lsdb.LsaWrapperImpl;
38import org.onosproject.ospf.controller.util.OspfInterfaceType;
39import org.onosproject.ospf.protocol.lsa.LsaHeader;
40import org.onosproject.ospf.protocol.lsa.OpaqueLsaHeader;
41import org.onosproject.ospf.protocol.lsa.types.OpaqueLsa10;
42import org.onosproject.ospf.protocol.lsa.types.TopLevelTlv;
43import org.onosproject.ospf.protocol.ospfpacket.OspfMessage;
44import org.onosproject.ospf.protocol.ospfpacket.OspfPacketHeader;
45import org.onosproject.ospf.protocol.ospfpacket.subtype.LsRequestPacket;
46import org.onosproject.ospf.protocol.ospfpacket.types.DdPacket;
47import org.onosproject.ospf.protocol.ospfpacket.types.LsAcknowledge;
48import org.onosproject.ospf.protocol.ospfpacket.types.LsRequest;
49import org.onosproject.ospf.protocol.ospfpacket.types.LsUpdate;
50import org.onosproject.ospf.protocol.util.ChecksumCalculator;
51import org.onosproject.ospf.protocol.util.OspfInterfaceState;
52import org.onosproject.ospf.protocol.util.OspfPacketType;
53import org.onosproject.ospf.protocol.util.OspfParameters;
54import org.onosproject.ospf.protocol.util.OspfUtil;
55import org.slf4j.Logger;
56import org.slf4j.LoggerFactory;
57
58import java.util.ArrayList;
59import java.util.HashMap;
60import java.util.Hashtable;
61import java.util.Iterator;
62import java.util.LinkedHashMap;
63import java.util.List;
64import java.util.ListIterator;
65import java.util.Map;
66import java.util.Set;
67import java.util.concurrent.CopyOnWriteArrayList;
68import java.util.concurrent.Executors;
69import java.util.concurrent.ScheduledExecutorService;
70import java.util.concurrent.TimeUnit;
71
72/**
73 * Represents an OSPF neighbor.
74 * The first thing an OSPF router must do is find its neighbors and form adjacency.
75 * Each neighbor that the router finds will be represented by this class.
76 */
77public class OspfNbrImpl implements OspfNbr {
78 private static final Logger log = LoggerFactory.getLogger(OspfNbrImpl.class);
79 private OspfNeighborState state;
80 private InternalRxmtDdPacket rxmtDdPacketTask;
81 private InternalInactivityTimeCheck inActivityTimeCheckTask;
82 private InternalFloodingTask floodingTask;
83 private InternalRxmtLsrPacket rxmtLsrPacketTask;
84 private ScheduledExecutorService exServiceRxmtLsr;
85 private ScheduledExecutorService exServiceFlooding;
86 private ScheduledExecutorService exServiceRxmtDDPacket;
87 private ScheduledExecutorService exServiceInActivity;
88
89 private boolean floodingTimerScheduled = false;
90 private boolean rxmtLsrTimerScheduled = false;
91 private boolean rxmtDdPacketTimerScheduled = false;
92 private boolean inActivityTimerScheduled = false;
93
94 /**
95 * When the two neighbors are exchanging databases, they form a master/slave relationship.
96 * The master sends the first Database Description Packet
97 */
98 private int isMaster;
99
100 /**
101 * The DD Sequence Number of the DD packet that is currently being sent to the neighbor.
102 */
103 private long ddSeqNum;
104
105 /**
106 * Another data structure for keeping information of the last received DD packet.
107 */
108 private DdPacket lastDdPacket;
109
110 /**
111 * Another data structure for keeping information of the last Sent DD packet.
112 */
113 private DdPacket lastSentDdPacket;
114
115 /**
116 * Another data structure for keeping information of the last Sent LSrequest packet.
117 */
118 private LsRequest lastSentLsrPacket;
119
120 /**
121 * The router ID of the Neighbor Router.
122 */
123 private Ip4Address neighborId;
124
125 /**
126 * The IP address of the neighboring router's interface to the attached network.
127 */
128 private Ip4Address neighborIpAddr;
129
130 /**
131 * The neighbor's IDEA of the designated router.
132 */
133 private Ip4Address neighborDr;
134
135 /**
136 * The neighbor's IDEA of the backup designated router.
137 */
138 private Ip4Address neighborBdr;
139
140 private int routerPriority;
141 private int routerDeadInterval;
142
143 /**
144 * The list of LSAs that have to be flooded.
145 */
146 private Map<String, OspfLsa> reTxList = new LinkedHashMap();
147
148 /**
149 * The list of LSAs that have been flooded but not yet acknowledged on this adjacency.
150 */
151 private Map<String, OspfLsa> pendingReTxList = new LinkedHashMap();
152
153 /**
154 * List of LSAs which are failed to received ACK.
155 */
156 private Map failedTxList = new HashMap();
157
158 /**
159 * The complete list of LSAs that make up the area link-state database, at the moment the.
160 * neighbor goes into Database Exchange state (EXCHANGE).
161 */
162 private List<LsaHeader> ddSummaryList = new CopyOnWriteArrayList();
163
164 /**
165 * LSA Request List from Neighbor.
166 */
167 private Hashtable lsReqList = new Hashtable();
168
169 /**
170 * The optional OSPF capabilities supported by the neighbor.
171 */
172 private int options;
173 private boolean isOpaqueCapable;
174
175 /**
176 * A link to the OSPF-Interface this Neighbor belongs to.
177 */
178 private OspfInterface ospfInterface;
179
180 /**
181 * A link to the OSPF-Area this Neighbor Data Structure belongs to.
182 */
183 private OspfArea ospfArea;
184 private OspfInterfaceChannelHandler handler;
185 private List<TopLevelTlv> topLevelTlvs = new ArrayList<>();
186 private List<DeviceInformation> deviceInformationList = new ArrayList<>();
187
188 private TopologyForDeviceAndLink topologyForDeviceAndLink;
189
190 /**
191 * Creates an instance of Neighbor.
192 *
193 * @param paramOspfArea OSPF Area instance
194 * @param paramOspfInterface OSPF interface instance
195 * @param ipAddr IP address
196 * @param routerId router id
197 * @param options options
198 * @param handler channel handler instance
199 * @param topologyForDeviceAndLinkCommon topology for device and link instance
200 */
201 public OspfNbrImpl(OspfArea paramOspfArea, OspfInterface paramOspfInterface,
202 Ip4Address ipAddr, Ip4Address routerId, int options,
203 OspfInterfaceChannelHandler handler, TopologyForDeviceAndLink topologyForDeviceAndLinkCommon) {
204 this.ospfArea = paramOspfArea;
205 this.ospfInterface = paramOspfInterface;
206 state = OspfNeighborState.DOWN;
207 isMaster = OspfUtil.NOT_MASTER;
208 ddSeqNum = OspfUtil.createRandomNumber();
209 neighborIpAddr = ipAddr;
210 neighborId = routerId;
211 this.options = options;
212 lastDdPacket = new DdPacket();
213 routerDeadInterval = paramOspfInterface.routerDeadIntervalTime();
214 this.handler = handler;
215 this.topologyForDeviceAndLink = topologyForDeviceAndLinkCommon;
216 }
217
218 /**
219 * Gets the IP address of this neighbor.
220 *
221 * @return the IP address of this neighbor
222 */
223 public Ip4Address neighborIpAddr() {
224 return neighborIpAddr;
225 }
226
227 /**
228 * Gets the neighbor is opaque enabled or not.
229 *
230 * @return true if the neighbor is opaque enabled else false.
231 */
232 public boolean isOpaqueCapable() {
233 return isOpaqueCapable;
234 }
235
236 /**
237 * Sets the neighbor is opaque enabled or not.
238 *
239 * @param isOpaqueCapable true if the neighbor is opaque enabledelse false
240 */
241 public void setIsOpaqueCapable(boolean isOpaqueCapable) {
242 this.isOpaqueCapable = isOpaqueCapable;
243 }
244
245 /**
246 * Have seen a Neighbor, but the Neighbor doesn't know about me.
247 *
248 * @param ospfHello Hello Packet instance
249 * @param channel netty channel instance
250 */
251 public void oneWayReceived(OspfMessage ospfHello, Channel channel) {
252 log.debug("OSPFNbr::oneWayReceived...!!!");
253 stopInactivityTimeCheck();
254 startInactivityTimeCheck();
255
256 if (state == OspfNeighborState.ATTEMPT) {
257 state = OspfNeighborState.INIT;
258 } else if (state == OspfNeighborState.DOWN) {
259 state = OspfNeighborState.INIT;
260 }
261
262 if (state.getValue() >= OspfNeighborState.TWOWAY.getValue()) {
263 state = OspfNeighborState.INIT;
264 failedTxList.clear();
265 ddSummaryList.clear();
266 lsReqList.clear();
267 }
268 }
269
270 /**
271 * Called when a DD OSPFMessage is received while state was INIT.
272 *
273 * @param ospfMessage ospf message instance
274 * @param channel netty channel instance
275 * @throws Exception might throws exception
276 */
277 public void twoWayReceived(OspfMessage ospfMessage, Channel channel) throws Exception {
278 log.debug("OSPFNbr::twoWayReceived...!!!");
279 stopInactivityTimeCheck();
280 startInactivityTimeCheck();
281 startFloodingTimer(channel);
282
283 OspfPacketHeader packet = (OspfPacketHeader) ospfMessage;
284 if (state.getValue() <= OspfNeighborState.TWOWAY.getValue()) {
285 if (formAdjacencyOrNot()) {
286 state = OspfNeighborState.EXSTART;
287
288 ddSeqNum++;
289 DdPacket ddPacket = new DdPacket();
290 // seting OSPF Header
291 ddPacket.setOspfVer(OspfUtil.OSPF_VERSION);
292 ddPacket.setOspftype(OspfPacketType.DD.value());
293 ddPacket.setRouterId(ospfArea.routerId());
294 ddPacket.setAreaId(ospfArea.areaId());
295 ddPacket.setAuthType(OspfUtil.NOT_ASSIGNED);
296 ddPacket.setAuthentication(OspfUtil.NOT_ASSIGNED);
297 ddPacket.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
298 ddPacket.setChecksum(OspfUtil.NOT_ASSIGNED);
299 boolean isOpaqueEnabled = ospfArea.isOpaqueEnabled();
300 if (isOpaqueEnabled) {
301 ddPacket.setOptions(ospfArea.opaqueEnabledOptions());
302 } else {
303 ddPacket.setOptions(ospfArea.options());
304 }
305 ddPacket.setIsInitialize(OspfUtil.INITIALIZE_SET);
306 ddPacket.setIsMore(OspfUtil.MORE_SET);
307 ddPacket.setIsMaster(OspfUtil.IS_MASTER);
308 ddPacket.setImtu(ospfInterface.mtu());
309 ddPacket.setSequenceNo(ddSeqNum);
310
311 setLastSentDdPacket(ddPacket);
312 rxmtDdPacketTask = new InternalRxmtDdPacket(channel);
313 startRxMtDdTimer(channel);
314 //setting destination ip
315 ddPacket.setDestinationIp(packet.sourceIp());
316 channel.write(ddPacket);
317 } else {
318 state = OspfNeighborState.TWOWAY;
319 }
320 }
321 }
322
323 /**
324 * Checks whether to form adjacency or not.
325 *
326 * @return true indicates form adjacency, else false
327 */
328 private boolean formAdjacencyOrNot() {
329 boolean formAdjacency = false;
330
331 if (ospfInterface.interfaceType() == OspfInterfaceType.POINT_TO_POINT.value()) {
332 formAdjacency = true;
333 } else if (ospfInterface.interfaceType() == OspfInterfaceType.BROADCAST.value()) {
334 if (ospfInterface.ipAddress().equals(this.neighborDr) ||
335 ospfInterface.ipAddress().equals(this.neighborBdr)) {
336 formAdjacency = true;
337 } else if (neighborBdr.equals(neighborIpAddr) ||
338 neighborDr.equals(neighborIpAddr)) {
339 formAdjacency = true;
340 }
341 }
342
343 log.debug("FormAdjacencyOrNot - neighborDR: {}, neighborBDR: {}, neighborIPAddr: {}, formAdjacencyOrNot {}",
344 neighborDr, neighborBdr, neighborIpAddr, formAdjacency);
345
346 return formAdjacency;
347 }
348
349 /**
350 * At this point Master/Slave relationship is definitely established.
351 * DD sequence numbers have been exchanged.
352 * This is the begin of sending/receiving of DD OSPFMessages.
353 *
354 * @param ospfMessage OSPF message instance
355 * @param neighborIsMaster neighbor is master or slave
356 * @param payload contains the LSAs to add in Dd Packet
357 * @param ch netty channel instance
358 * @throws Exception might throws exception
359 */
360 public void negotiationDone(OspfMessage ospfMessage,
361 boolean neighborIsMaster, List payload, Channel ch) throws Exception {
362 stopRxMtDdTimer();
363 OspfPacketHeader packet = (OspfPacketHeader) ospfMessage;
364 DdPacket ddPacketForCheck = (DdPacket) packet;
365 if (ddPacketForCheck.isOpaqueCapable()) {
366 OspfLsdb database = ospfArea.database();
367 List opaqueLsas = database.getAllLsaHeaders(true, true);
368 Iterator iterator = opaqueLsas.iterator();
369 while (iterator.hasNext()) {
370 OspfLsa ospfLsa = (OspfLsa) iterator.next();
371 if (ospfLsa.getOspfLsaType() == OspfLsaType.AREA_LOCAL_OPAQUE_LSA) {
372 OpaqueLsa10 opaqueLsa10 = (OpaqueLsa10) ospfLsa;
373 topLevelTlvs = opaqueLsa10.topLevelValues();
374 }
375 }
376 }
377 if (state == OspfNeighborState.EXSTART) {
378 state = OspfNeighborState.EXCHANGE;
379 boolean excludeMaxAgeLsa = true;
380 //list of contents of area wise LSA
381 ddSummaryList = (CopyOnWriteArrayList) ospfArea.getLsaHeaders(excludeMaxAgeLsa, isOpaqueCapable);
382
383 if (neighborIsMaster) {
384 processLsas(payload);
385 // ...construct new DD Packet...
386 DdPacket ddPacket = new DdPacket();
387 // setting OSPF Header
388 ddPacket.setOspfVer(OspfUtil.OSPF_VERSION);
389 ddPacket.setOspftype(OspfPacketType.DD.value());
390 ddPacket.setRouterId(ospfArea.routerId());
391 ddPacket.setAreaId(ospfArea.areaId());
392 ddPacket.setAuthType(OspfUtil.NOT_ASSIGNED);
393 ddPacket.setAuthentication(OspfUtil.NOT_ASSIGNED);
394 ddPacket.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
395 ddPacket.setChecksum(OspfUtil.NOT_ASSIGNED);
396 boolean isOpaqueEnabled = ospfArea.isOpaqueEnabled();
397 if (isOpaqueEnabled && isOpaqueCapable) {
398 ddPacket.setOptions(ospfArea.opaqueEnabledOptions());
399 } else {
400 ddPacket.setOptions(ospfArea.options());
401 }
402 ddPacket.setIsInitialize(OspfUtil.INITIALIZE_NOTSET);
403 ddPacket.setIsMore(OspfUtil.MORE_NOTSET);
404 ddPacket.setIsMaster(OspfUtil.NOT_MASTER);
405 ddPacket.setImtu(ospfInterface.mtu());
406 ddPacket.setSequenceNo(ddSeqNum);
407 //setting the destination
408 ddPacket.setDestinationIp(packet.sourceIp());
409 setLastSentDdPacket(ddPacket);
410 getIsMoreBit();
411
412 ch.write(lastSentDdPacket());
413 } else {
414 // process LSA Vector's List, Add it to LSRequestList.
415 processLsas(payload);
416 DdPacket ddPacket = new DdPacket();
417 // setting OSPF Header
418 ddPacket.setOspfVer(OspfUtil.OSPF_VERSION);
419 ddPacket.setOspftype(OspfPacketType.DD.value());
420 ddPacket.setRouterId(ospfArea.routerId());
421 ddPacket.setAreaId(ospfArea.areaId());
422 ddPacket.setAuthType(OspfUtil.NOT_ASSIGNED);
423 ddPacket.setAuthentication(OspfUtil.NOT_ASSIGNED);
424 ddPacket.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
425 ddPacket.setChecksum(OspfUtil.NOT_ASSIGNED);
426 boolean isOpaqueEnabled = ospfArea.isOpaqueEnabled();
427 if (isOpaqueEnabled && isOpaqueCapable) {
428 ddPacket.setOptions(ospfArea.opaqueEnabledOptions());
429 } else {
430 ddPacket.setOptions(ospfArea.options());
431 }
432 ddPacket.setIsInitialize(OspfUtil.INITIALIZE_NOTSET);
433 ddPacket.setIsMore(OspfUtil.MORE_NOTSET);
434 ddPacket.setIsMaster(OspfUtil.IS_MASTER);
435 ddPacket.setImtu(ospfInterface.mtu());
436 ddPacket.setSequenceNo(ddSeqNum);
437 setLastSentDdPacket(ddPacket);
438 getIsMoreBit();
439 ddPacket.setDestinationIp(packet.sourceIp());
440 ch.write(lastSentDdPacket());
441 startRxMtDdTimer(ch);
442 }
443 }
444 }
445
446 /**
447 * Process the LSA Headers received in the last received Database Description OSPFMessage.
448 *
449 * @param ddPayload LSA headers to process
450 * @throws Exception might throws exception
451 */
452 public void processLsas(List ddPayload) throws Exception {
453 log.debug("OSPFNbr::processLsas...!!!");
454 OspfLsa nextLsa;
455 Iterator lsas = ddPayload.iterator();
456 while (lsas.hasNext()) {
457 nextLsa = (OspfLsa) lsas.next();
458 // check LSA Type.
459 if (((nextLsa.getOspfLsaType().value() > OspfLsaType.EXTERNAL_LSA.value()) &&
460 (nextLsa.getOspfLsaType().value() < OspfLsaType.LINK_LOCAL_OPAQUE_LSA.value())) ||
461 (nextLsa.getOspfLsaType().value() > OspfLsaType.AS_OPAQUE_LSA.value())) {
462 // unknown lsType found!
463 seqNumMismatch("LS Type found was unknown.");
464 return;
465 }
466
467 if ((nextLsa.getOspfLsaType() == OspfLsaType.EXTERNAL_LSA) &&
468 !ospfArea.isExternalRoutingCapability()) {
469 // LSA is external and the Area has no external lsa capability
470 seqNumMismatch("External LSA found although area is stub.");
471 return;
472 }
473
474 LsaWrapper lsaHasInstance = ospfArea.lsaLookup(nextLsa);
475 if (lsaHasInstance == null) {
476 lsReqList.put(((OspfAreaImpl) ospfArea).getLsaKey((LsaHeader) nextLsa), nextLsa);
477 } else {
478 String isNew = ((OspfAreaImpl) ospfArea).isNewerOrSameLsa(nextLsa,
479 lsaHasInstance.ospfLsa());
480 if (isNew.equals("latest")) {
481 lsReqList.put(((OspfAreaImpl) ospfArea).getLsaKey((LsaHeader) nextLsa), nextLsa);
482 }
483 }
484 }
485 }
486
487 /**
488 * Handles sequence number mis match event.
489 *
490 * @param reason a string represents the mismatch reason
491 * @return OSPF message instance
492 * @throws Exception might throws exception
493 */
494 public OspfMessage seqNumMismatch(String reason) throws Exception {
495 log.debug("OSPFNbr::seqNumMismatch...{} ", reason);
496 stopRxMtDdTimer();
497
498 if (state.getValue() >= OspfNeighborState.EXCHANGE.getValue()) {
499 /* if (state == OspfNeighborState.FULL) {
500 ospfArea.refreshArea(ospfInterface);
501 }*/
502
503 state = OspfNeighborState.EXSTART;
504 lsReqList.clear();
505 ddSummaryList.clear();
506 //increment the dd sequence number
507 ddSeqNum++;
508
509 DdPacket ddPacket = new DdPacket();
510 // seting OSPF Header
511 ddPacket.setOspfVer(OspfUtil.OSPF_VERSION);
512 ddPacket.setOspftype(OspfPacketType.DD.value());
513 ddPacket.setRouterId(ospfArea.routerId());
514 ddPacket.setAreaId(ospfArea.areaId());
515 ddPacket.setAuthType(OspfUtil.NOT_ASSIGNED);
516 ddPacket.setAuthentication(OspfUtil.NOT_ASSIGNED);
517 ddPacket.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
518 ddPacket.setChecksum(OspfUtil.NOT_ASSIGNED);
519 boolean isOpaqueEnabled = ospfArea.isOpaqueEnabled();
520 if (isOpaqueEnabled) {
521 ddPacket.setOptions(ospfArea.opaqueEnabledOptions());
522 } else {
523 ddPacket.setOptions(ospfArea.options());
524 }
525 ddPacket.setIsInitialize(OspfUtil.INITIALIZE_SET);
526 ddPacket.setIsMore(OspfUtil.MORE_SET);
527 ddPacket.setIsMaster(OspfUtil.IS_MASTER);
528 ddPacket.setImtu(ospfInterface.mtu());
529 ddPacket.setSequenceNo(ddSeqNum);
530
531 setLastSentDdPacket(ddPacket);
532 //setting destination ip
533 ddPacket.setDestinationIp(neighborIpAddr());
534 setLastSentDdPacket(ddPacket);
535
536 return ddPacket;
537 }
538
539 return null;
540 }
541
542 /**
543 * Called if a LS Request has been received for an LSA which is not contained in the database.
544 * This indicates an error in the Database Exchange process.
545 * Actions to be performed are the same as in seqNumMismatch.
546 * In addition, stop the possibly activated re transmission timer.
547 *
548 * @param ch netty channel instance
549 */
550 public void badLSReq(Channel ch) throws Exception {
551 log.debug("OSPFNbr::badLSReq...!!!");
552
553 if (state.getValue() >= OspfNeighborState.EXCHANGE.getValue()) {
554 if (state == OspfNeighborState.FULL) {
555 ospfArea.refreshArea(ospfInterface);
556 }
557
558 stopRxMtDdTimer();
559 state = OspfNeighborState.EXSTART;
560
561 lsReqList.clear();
562 ddSummaryList.clear();
563 reTxList.clear();
564 //increment the dd sequence number
565 isMaster = OspfUtil.IS_MASTER;
566 ddSeqNum++;
567 DdPacket ddPacket = new DdPacket();
568 // seting OSPF Header
569 ddPacket.setOspfVer(OspfUtil.OSPF_VERSION);
570 ddPacket.setOspftype(OspfPacketType.DD.value());
571 ddPacket.setRouterId(ospfArea.routerId());
572 ddPacket.setAreaId(ospfArea.areaId());
573 ddPacket.setAuthType(OspfUtil.NOT_ASSIGNED);
574 ddPacket.setAuthentication(OspfUtil.NOT_ASSIGNED);
575 ddPacket.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
576 ddPacket.setChecksum(OspfUtil.NOT_ASSIGNED);
577
578 // setting DD Body
579 boolean isOpaqueEnabled = ospfArea.isOpaqueEnabled();
580 if (isOpaqueEnabled && this.isOpaqueCapable) {
581 ddPacket.setOptions(ospfArea.opaqueEnabledOptions());
582 } else {
583 ddPacket.setOptions(ospfArea.options());
584 }
585 ddPacket.setIsInitialize(OspfUtil.INITIALIZE_SET);
586 ddPacket.setIsMore(OspfUtil.MORE_SET);
587 ddPacket.setIsMaster(OspfUtil.IS_MASTER);
588 ddPacket.setImtu(ospfInterface.mtu());
589 ddPacket.setSequenceNo(ddSeqNum);
590
591 rxmtDdPacketTask = new InternalRxmtDdPacket(ch);
592 startRxMtDdTimer(ch);
593
594 //setting destination ip
595 ddPacket.setDestinationIp(neighborIpAddr());
596 setLastSentDdPacket(ddPacket);
597 ch.write(ddPacket);
598 }
599 }
600
601 /**
602 * Called if state is EXCHANGE. This method is executed every time a DD Packets arrives.
603 * When the last Packet arrives, it transfers the state into LOADING or FULL
604 *
605 * @param neighborIsMaster true if neighbor is master else false
606 * @param dataDescPkt DdPacket instance
607 * @param ch netty channel instance
608 * @throws Exception might throws exception
609 */
610 public void processDdPacket(boolean neighborIsMaster, DdPacket dataDescPkt,
611 Channel ch) throws Exception {
612 log.debug("OSPFNbr::neighborIsMaster.{}", neighborIsMaster);
613
614 if (!neighborIsMaster) {
615 stopRxMtDdTimer();
616 ddSeqNum++;
617 processLsas(dataDescPkt.getLsaHeaderList());
618 if ((ddSummaryList.isEmpty()) &&
619 (dataDescPkt.isMore() == OspfUtil.MORE_NOTSET)) {
620 log.debug(
621 "OSPFNbr::ddSummaryList is empty and dataDescPkt.isMore is zero..!!!");
622 // generate the neighbor event ExchangeDone.
623 exchangeDone(dataDescPkt, ch);
624 } else {
625 log.debug("OSPFNbr::ddSummaryList is present...!!!");
626 // send a new Database Description Packet to the slave.
627 DdPacket ddPacket = new DdPacket();
628 // seting OSPF Header
629 ddPacket.setOspfVer(OspfUtil.OSPF_VERSION);
630 ddPacket.setOspftype(OspfPacketType.DD.value());
631 ddPacket.setRouterId(ospfArea.routerId());
632 ddPacket.setAreaId(ospfArea.areaId());
633 ddPacket.setAuthType(OspfUtil.NOT_ASSIGNED);
634 ddPacket.setAuthentication(OspfUtil.NOT_ASSIGNED);
635 ddPacket.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
636 ddPacket.setChecksum(OspfUtil.NOT_ASSIGNED);
637 // setting DD Body
638 boolean isOpaqueEnabled = ospfArea.isOpaqueEnabled();
639 if (isOpaqueEnabled && isOpaqueCapable) {
640 ddPacket.setOptions(ospfArea.opaqueEnabledOptions());
641 } else {
642 ddPacket.setOptions(ospfArea.options());
643 }
644 ddPacket.setIsInitialize(OspfUtil.INITIALIZE_NOTSET);
645 ddPacket.setIsMore(OspfUtil.MORE_NOTSET);
646 ddPacket.setIsMaster(OspfUtil.IS_MASTER);
647 ddPacket.setImtu(ospfInterface.mtu());
648 ddPacket.setSequenceNo(ddSeqNum);
649
650 setLastSentDdPacket(ddPacket);
651 getIsMoreBit();
652 //Set the destination IP Address
653 ddPacket.setDestinationIp(dataDescPkt.sourceIp());
654 ch.write(lastSentDdPacket());
655
656 startRxMtDdTimer(ch);
657 }
658 } else {
659 log.debug("OSPFNbr::neighborIsMaster is master...!!!");
660 ddSeqNum = dataDescPkt.sequenceNo();
661 processLsas(dataDescPkt.getLsaHeaderList());
662
663 DdPacket ddPacket = new DdPacket();
664 // seting OSPF Header
665 ddPacket.setOspfVer(OspfUtil.OSPF_VERSION);
666 ddPacket.setOspftype(OspfPacketType.DD.value());
667 ddPacket.setRouterId(ospfArea.routerId());
668 ddPacket.setAreaId(ospfArea.areaId());
669 ddPacket.setAuthType(OspfUtil.NOT_ASSIGNED);
670 ddPacket.setAuthentication(OspfUtil.NOT_ASSIGNED);
671 ddPacket.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
672 ddPacket.setChecksum(OspfUtil.NOT_ASSIGNED);
673 // setting DD Body
674 boolean isOpaqueEnabled = ospfArea.isOpaqueEnabled();
675 if (isOpaqueEnabled && this.isOpaqueCapable) {
676 ddPacket.setOptions(ospfArea.opaqueEnabledOptions());
677 } else {
678 ddPacket.setOptions(ospfArea.options());
679 }
680 ddPacket.setIsInitialize(OspfUtil.INITIALIZE_NOTSET);
681 ddPacket.setIsMore(OspfUtil.MORE_NOTSET);
682 ddPacket.setIsMaster(OspfUtil.NOT_MASTER);
683 ddPacket.setImtu(ospfInterface.mtu());
684 ddPacket.setSequenceNo(ddSeqNum);
685 setLastSentDdPacket(ddPacket);
686 getIsMoreBit();
687
688 if ((ddPacket.isMore() == OspfUtil.MORE_NOTSET) &&
689 (dataDescPkt.isMore() == OspfUtil.MORE_NOTSET)) {
690 // generate the neighbor event ExchangeDone.
691 exchangeDone(dataDescPkt, ch);
692 }
693
694 ddPacket.setDestinationIp(dataDescPkt.sourceIp());
695 ch.write(ddPacket);
696 }
697 }
698
699 /**
700 * Sets the more bit in stored, last sent DdPacket.
701 */
702 private void getIsMoreBit() {
703 DdPacket ddPacket = lastSentDdPacket();
704 int count = ddSummaryList.size();
705
706 if (!ddSummaryList.isEmpty()) {
707 Iterator itr = ddSummaryList.iterator();
708 int currentLength = OspfUtil.DD_HEADER_LENGTH;
709 int maxSize = ospfInterface.mtu() - OspfUtil.LSA_HEADER_LENGTH; // subtract a normal IP header.
710 while (itr.hasNext()) {
711 if ((currentLength + OspfUtil.LSA_HEADER_LENGTH) > maxSize) {
712 break;
713 }
714
715 LsaHeader lsaHeader = (LsaHeader) itr.next();
716 ddPacket.addLsaHeader(lsaHeader);
717 currentLength = currentLength + OspfUtil.LSA_HEADER_LENGTH;
718 ddSummaryList.remove(lsaHeader);
719 count--;
720 }
721
722 if (count > 0) {
723 ddPacket.setIsMore(OspfUtil.MORE_SET);
724 } else {
725 ddPacket.setIsMore(OspfUtil.MORE_NOTSET);
726 }
727 }
728
729 setLastSentDdPacket(ddPacket);
730 }
731
732 /**
733 * At this point, the router has sent and received an entire sequence of DD packets.
734 * Now it must be determined whether the new state is FULL, or LS Request packets
735 * have to be send.
736 *
737 * @param message OSPF message instance
738 * @param ch netty channel handler
739 */
740 public void exchangeDone(OspfMessage message, Channel ch) {
741 log.debug("OSPFNbr::exchangeDone...!!!");
742 stopRxMtDdTimer();
743
744 OspfPacketHeader header = (OspfPacketHeader) message;
745
746 if (state == OspfNeighborState.EXCHANGE) {
747 if (lsReqList.isEmpty()) {
748 state = OspfNeighborState.FULL;
749 //handler.addDeviceInformation(this);
750 //handler.addLinkInformation(this, topLevelTlvs);
751 } else {
752 state = OspfNeighborState.LOADING;
753 LsRequest lsRequest = buildLsRequest();
754 //Setting the destination address
755 lsRequest.setDestinationIp(header.sourceIp());
756 ch.write(lsRequest);
757
758 setLastSentLsrPacket(lsRequest);
759 startRxMtLsrTimer(ch);
760 }
761 }
762 }
763
764 /**
765 * Builds LS Request.
766 *
767 * @return ls request instance
768 */
769 private LsRequest buildLsRequest() {
770 //send link state request packet to neighbor
771 //for recent lsa's which are not received in exchange state
772 LsRequest lsRequest = new LsRequest();
773 lsRequest.setOspfVer(OspfUtil.OSPF_VERSION);
774 lsRequest.setOspftype(OspfPacketType.LSREQUEST.value());
775 lsRequest.setRouterId(ospfArea.routerId());
776 lsRequest.setAreaId(ospfArea.areaId());
777 lsRequest.setAuthType(OspfUtil.NOT_ASSIGNED);
778 lsRequest.setAuthentication(OspfUtil.NOT_ASSIGNED);
779 lsRequest.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
780 lsRequest.setChecksum(OspfUtil.NOT_ASSIGNED);
781
782 Set lsaKeys = lsReqList.keySet();
783 Iterator itr = lsaKeys.iterator();
784
785 int currentLength = OspfUtil.OSPF_HEADER_LENGTH;
786 int maxSize = ospfInterface.mtu() -
787 OspfUtil.LSA_HEADER_LENGTH; // subtract a normal IP header.
788
789 while (itr.hasNext()) {
790 if ((currentLength + OspfUtil.LSREQUEST_LENGTH) >= maxSize) {
791 break;
792 }
793 LsRequestPacket lsRequestPacket = new LsRequestPacket();
794
795 String key = ((String) itr.next());
796 String[] lsaKey = key.split("-");
797 OspfLsa lsa = (OspfLsa) lsReqList.get(key);
798
799 lsRequestPacket.setLsType(Integer.valueOf(lsaKey[0]));
800 lsRequestPacket.setOwnRouterId(lsaKey[2]);
801
802 if (((lsa.getOspfLsaType().value() == OspfLsaType.AREA_LOCAL_OPAQUE_LSA.value()) ||
803 (lsa.getOspfLsaType().value() == OspfLsaType.LINK_LOCAL_OPAQUE_LSA.value())) ||
804 (lsa.getOspfLsaType().value() == OspfLsaType.AS_OPAQUE_LSA.value())) {
805 OpaqueLsaHeader header = (OpaqueLsaHeader) lsa;
806 byte[] opaqueIdBytes = OspfUtil.convertToTwoBytes(header.opaqueId());
807 lsRequestPacket.setLinkStateId(header.opaqueType() + "." + "0" + "." + opaqueIdBytes[0]
808 + "." + opaqueIdBytes[1]);
809 } else {
810 lsRequestPacket.setLinkStateId(lsaKey[1]);
811 }
812
813 lsRequest.addLinkStateRequests(lsRequestPacket);
814 currentLength = currentLength + OspfUtil.LSREQUEST_LENGTH;
815 }
816
817 return lsRequest;
818 }
819
820 /**
821 * Determines whether an adjacency should be established/maintained with the neighbor or not.
822 *
823 * @param ch netty channel instance
824 */
825 public void adjOk(Channel ch) {
826 log.debug("OSPFNbr::adjOk...!!!");
827 if (ospfInterface.interfaceType() != OspfInterfaceType.POINT_TO_POINT.value()) {
828 if (state == OspfNeighborState.TWOWAY) {
829 if (formAdjacencyOrNot()) {
830 state = OspfNeighborState.EXSTART;
831 //check for sequence number in lsdb
832 ddSeqNum++;
833
834 DdPacket ddPacket = new DdPacket();
835 // seting OSPF Header
836 ddPacket.setOspfVer(OspfUtil.OSPF_VERSION);
837 ddPacket.setOspftype(OspfPacketType.DD.value());
838 ddPacket.setRouterId(ospfArea.routerId());
839 ddPacket.setAreaId(ospfArea.areaId());
840 ddPacket.setAuthType(OspfUtil.NOT_ASSIGNED);
841 ddPacket.setAuthentication(OspfUtil.NOT_ASSIGNED);
842 ddPacket.setOspfPacLength(OspfUtil.NOT_ASSIGNED);
843 ddPacket.setChecksum(OspfUtil.NOT_ASSIGNED);
844
845 // setting DD Body
846 boolean isOpaqueEnabled = ospfArea.isOpaqueEnabled();
847 if (isOpaqueEnabled && this.isOpaqueCapable) {
848 ddPacket.setOptions(ospfArea.opaqueEnabledOptions());
849 } else {
850 ddPacket.setOptions(ospfArea.options());
851 }
852 ddPacket.setIsInitialize(OspfUtil.INITIALIZE_SET);
853 ddPacket.setIsMore(OspfUtil.MORE_SET);
854 ddPacket.setIsMaster(OspfUtil.IS_MASTER);
855 ddPacket.setImtu(ospfInterface.mtu());
856 ddPacket.setSequenceNo(ddSeqNum);
857 rxmtDdPacketTask = new InternalRxmtDdPacket(ch);
858 startRxMtDdTimer(ch);
859 //setting destination ip
860 ddPacket.setDestinationIp(neighborIpAddr());
861 setLastSentDdPacket(ddPacket);
862 ch.write(ddPacket);
863 }
864 } else if (state.getValue() >= OspfNeighborState.EXSTART.getValue()) {
865 if (!formAdjacencyOrNot()) {
866 state = OspfNeighborState.TWOWAY;
867 lsReqList.clear();
868 ddSummaryList.clear();
869 reTxList.clear();
870 }
871 }
872 }
873 }
874
875 /**
876 * LS Update Packet has been received while state was EXCHANGE or LOADING.
877 * Examine the received LSAs, check whether they were requested or not and process
878 * them accordingly. Therefore use method "processReceivedLsa" for further treatment.
879 *
880 * @param lsUpdPkt LS Update Packet received while Neighbor state was EXCHANGE or
881 * LOADING
882 * @param ch netty channel instance
883 * @throws Exception might throws exception
884 */
885 public void processLsUpdate(LsUpdate lsUpdPkt, Channel ch) throws Exception {
886 stopRxMtLsrTimer();
887 log.debug("OSPFNbr::processLsUpdate...!!!");
888
889 List lsaList = lsUpdPkt.getLsaList();
890 if (!lsaList.isEmpty()) {
891 Iterator itr = lsaList.iterator();
892
893 while (itr.hasNext()) {
894 LsaHeader lsaHeader = (LsaHeader) itr.next();
895 String key = ((OspfAreaImpl) ospfArea).getLsaKey(lsaHeader);
896
897 if (lsReqList.containsKey(key)) {
898 boolean removeIt;
899 removeIt = processReceivedLsa(lsaHeader, false, ch,
900 lsUpdPkt.sourceIp());
901 if (removeIt) {
902 lsReqList.remove(key);
903 }
904 } else {
905 // LSA was received via Flooding
906 processReceivedLsa(lsaHeader, true, ch,
907 lsUpdPkt.sourceIp());
908 }
909 }
910
911 if (lsReqList.isEmpty() && (state == OspfNeighborState.LOADING)) {
912 // loading complete
913 loadingDone();
914 } else {
915 stopRxMtLsrTimer();
916 LsRequest lsRequest = buildLsRequest();
917 lsRequest.setDestinationIp(lsUpdPkt.sourceIp());
918 setLastSentLsrPacket(lsRequest);
919
920 startRxMtLsrTimer(ch);
921 }
922 }
923 }
924
925 /***
926 * Method gets called when no more ls request list and moving to FULL State.
927 *
928 * @throws Exception might throws exception
929 */
930 public void loadingDone() throws Exception {
931 stopRxMtLsrTimer();
932 stopRxMtDdTimer();
933 log.debug("OSPFNbr::loadingDone...!!!");
934 state = OspfNeighborState.FULL;
935 ospfArea.refreshArea(ospfInterface);
936 }
937
938 /**
939 * Adds device and link.
940 *
941 * @param topologyForDeviceAndLink topology for device and link instance
942 */
943 private void callDeviceAndLinkAdding(TopologyForDeviceAndLink topologyForDeviceAndLink) {
944 Map<String, DeviceInformation> deviceInformationMap = topologyForDeviceAndLink.deviceInformationMap();
945 Map<String, LinkInformation> linkInformationMap = topologyForDeviceAndLink.linkInformationMap();
946 OspfRouter ospfRouter = new OspfRouterImpl();
947 log.debug("Device Information in list format along with size {}", deviceInformationMap.size());
948 for (String key : deviceInformationMap.keySet()) {
949 DeviceInformation value = deviceInformationMap.get(key);
950 ospfRouter.setRouterIp(value.routerId());
951 ospfRouter.setAreaIdOfInterface(ospfArea.areaId());
952 ospfRouter.setNeighborRouterId(value.deviceId());
953 OspfDeviceTed ospfDeviceTed = new OspfDeviceTedImpl();
954 List<Ip4Address> ip4Addresses = value.interfaceId();
955 ospfDeviceTed.setIpv4RouterIds(ip4Addresses);
956 ospfRouter.setDeviceTed(ospfDeviceTed);
957 ospfRouter.setOpaque(ospfArea.isOpaqueEnabled());
958 if (value.isDr()) {
959 ospfRouter.setDr(value.isDr());
960 } else {
961 ospfRouter.setDr(false);
962 }
963 int size = value.interfaceId().size();
964 for (int i = 0; i < size; i++) {
965 ospfRouter.setInterfaceId(value.interfaceId().get(i));
966 }
967 if (value.isAlreadyCreated()) {
968 removeDeviceDetails(value.routerId());
969 OspfRouter ospfRouter1 = new OspfRouterImpl();
970 ospfRouter1.setRouterIp(value.routerId());
971 ospfRouter1.setInterfaceId(ospfInterface.ipAddress());
972 ospfRouter1.setAreaIdOfInterface(ospfArea.areaId());
973 ospfRouter1.setDeviceTed(new OspfDeviceTedImpl());
974 topologyForDeviceAndLink.removeLinks(value.routerId());
975 handler.removeDeviceInformation(ospfRouter1);
976 }
977 handler.addDeviceInformation(ospfRouter);
978 }
979 for (Map.Entry<String, LinkInformation> entry : linkInformationMap.entrySet()) {
980 String key = entry.getKey();
981 LinkInformation value = entry.getValue();
982 OspfRouter ospfRouterForLink = new OspfRouterImpl();
983 ospfRouterForLink.setInterfaceId(value.interfaceIp());
984 ospfRouterForLink.setAreaIdOfInterface(ospfArea.areaId());
985 ospfRouterForLink.setOpaque(ospfArea.isOpaqueEnabled());
986 OspfLinkTed ospfLinkTed =
987 topologyForDeviceAndLink.getOspfLinkTedHashMap(value.linkDestinationId().toString());
988 if (ospfLinkTed == null) {
989 ospfLinkTed = new OspfLinkTedImpl();
990 ospfLinkTed.setMaximumLink(Bandwidth.bps(0));
991 ospfLinkTed.setMaxReserved(Bandwidth.bps(0));
992 ospfLinkTed.setTeMetric(0);
993 }
994
995 if (!value.isLinkSrcIdNotRouterId()) {
996 ospfRouterForLink.setRouterIp(value.linkSourceId());
997 ospfRouterForLink.setNeighborRouterId(value.linkDestinationId());
998 try {
999 handler.addLinkInformation(ospfRouterForLink, ospfLinkTed);
1000 log.debug("LinkId, LinkSrc , LinkDest , LinkInterface values are : "
1001 + value.linkId() + " , " + value.linkSourceId() + " , "
1002 + value.linkDestinationId() + " , "
1003 + value.interfaceIp());
1004 } catch (Exception e) {
1005 log.debug("Got Exception : {}", e.getMessage());
1006 }
1007 }
1008 }
1009 }
1010
1011 // RFC 2328 Section 13 - partly as flooding procedure
1012
1013 /**
1014 * Processes the received Lsa.
1015 *
1016 * @param recLsa received Lsa
1017 * @param receivedViaFlooding received via flooding or not
1018 * @param ch channel instance
1019 * @param sourceIp source of this Lsa
1020 * @return true to remove it from lsReqList else false
1021 * @throws Exception might throws exception
1022 */
1023 public boolean processReceivedLsa(LsaHeader recLsa,
1024 boolean receivedViaFlooding, Channel ch, Ip4Address sourceIp)
1025 throws Exception {
1026 log.debug("OSPFNbr::processReceivedLsa(recLsa, recievedViaFlooding, ch)...!!!");
1027
1028 //Validate the lsa checksum RFC 2328 13 (1)
1029 ChecksumCalculator checkSum = new ChecksumCalculator();
1030 if (!checkSum.isValidLsaCheckSum(recLsa,
1031 recLsa.getOspfLsaType().value(),
1032 OspfUtil.LSAPACKET_CHECKSUM_POS1,
1033 OspfUtil.LSAPACKET_CHECKSUM_POS2)) {
1034 log.debug("Checksum mismatch. Received LSA packet type {} ",
1035 recLsa.lsType());
1036
1037 return true;
1038 }
1039
1040 //If LSA type is unknown discard the lsa RFC 2328 13(2)
1041 if (((recLsa.getOspfLsaType().value() > OspfLsaType.EXTERNAL_LSA.value()) &&
1042 (recLsa.getOspfLsaType().value() < OspfLsaType.LINK_LOCAL_OPAQUE_LSA.value())) ||
1043 (recLsa.getOspfLsaType().value() > OspfLsaType.AS_OPAQUE_LSA.value())) {
1044 return true;
1045 }
1046
1047 //If LSA type is external & the area is configured as stub area discard the lsa RFC 2328 13(3)
1048 if ((recLsa.getOspfLsaType() == OspfLsaType.EXTERNAL_LSA) &&
1049 (!ospfArea.isExternalRoutingCapability())) // to determine how to store options
1050 {
1051 return true;
1052 }
1053
1054 //if lsa age is equal to maxage && instance is not in lsdb && none of neighbors are in exchange
1055 // or loading state
1056 // Acknowledge the receipt by sending LSAck to the sender. 2328 13(4)
1057 if ((recLsa.age() == OspfParameters.MAXAGE) &&
1058 (ospfArea.lsaLookup(recLsa) == null) &&
1059 ospfArea.noNeighborInLsaExchangeProcess()) {
1060 // RFC 2328 Section 13. (4)
1061 // Because the LSA was not yet requested, it is treated as a flooded LSA and thus
1062 // acknowledged.
1063 directAcknowledge(recLsa, ch, sourceIp);
1064 return true;
1065 }
1066
1067 String key = ((OspfAreaImpl) ospfArea).getLsaKey(recLsa);
1068 LsaWrapper lsWrapper = ospfArea.lsaLookup(recLsa);
1069 String status = isNullorLatest(lsWrapper, recLsa);
1070 //Section 13 (5)
1071 if (status.equals("isNullorLatest")) {
1072
1073 if (recLsa.lsType() == OspfLsaType.ROUTER.value() && recLsa.advertisingRouter().equals(
1074 ospfArea.routerId())) {
1075 if (recLsa.lsSequenceNo() > ((LsaWrapperImpl) lsWrapper).lsaHeader().lsSequenceNo()) {
1076 ospfArea.setDbRouterSequenceNumber(recLsa.lsSequenceNo() + 1);
1077 processSelfOriginatedLsa();
1078 }
1079
1080 if (recLsa.age() == OspfParameters.MAXAGE) {
1081 ((LsaWrapperImpl) lsWrapper).lsaHeader().setAge(OspfParameters.MAXAGE);
1082 //remove from db & bin, add the lsa to MaxAge bin.
1083 ospfArea.addLsaToMaxAgeBin(((OspfAreaImpl) ospfArea).getLsaKey(((LsaWrapperImpl)
1084 lsWrapper).lsaHeader()), lsWrapper);
1085 ospfArea.removeLsaFromBin(lsWrapper);
1086 }
1087
1088 return true;
1089 } else if (recLsa.lsType() == OspfLsaType.NETWORK.value() && isLinkStateMatchesOwnRouterId(
1090 recLsa.linkStateId())) {
1091 // if we are not DR or if origination router ID not equal to our router ID //either
1092 // DR state changed or our router ID was changed
1093 //set LSAge = MaxAge
1094 //flood the LSA
1095 if (((OspfInterfaceImpl) ospfInterface).state() != OspfInterfaceState.DR ||
1096 !recLsa.advertisingRouter().equals(
1097 ospfArea.routerId())) {
1098 if (lsWrapper != null) {
1099 ((LsaWrapperImpl) lsWrapper).lsaHeader().setAge(OspfParameters.MAXAGE);
1100 //remove from bin, add the lsa to MaxAge bin.
1101 ospfArea.addLsaToMaxAgeBin(((OspfAreaImpl) ospfArea).getLsaKey(((LsaWrapperImpl)
1102 lsWrapper).lsaHeader()), lsWrapper);
1103 ospfArea.removeLsaFromBin(lsWrapper);
1104 } else {
1105 recLsa.setAge(OspfParameters.MAXAGE);
1106 ((OspfAreaImpl) ospfArea).addToOtherNeighborLsaTxList(recLsa);
1107 }
1108 }
1109
1110 return true;
1111 } else {
1112 if (recLsa.age() == OspfParameters.MAXAGE) {
1113 ((OspfInterfaceImpl) ospfInterface).addLsaHeaderForDelayAck(recLsa);
1114 //remove from db & bin, add the lsa to MaxAge bin.
1115 if (lsWrapper != null) {
1116 lsWrapper.setLsaAgeReceived(OspfParameters.MAXAGE);
1117 ospfArea.addLsaToMaxAgeBin(((OspfAreaImpl) ospfArea).getLsaKey(((LsaWrapperImpl)
1118 lsWrapper).lsaHeader()), lsWrapper);
1119 ospfArea.removeLsaFromBin(lsWrapper);
1120 } else {
1121 ((OspfAreaImpl) ospfArea).addToOtherNeighborLsaTxList(recLsa);
1122 }
1123
1124 return true;
1125 } else {
1126 ospfArea.addLsa(recLsa, ospfInterface);
1127 log.debug("Inside addLsaMethod");
1128 topologyForDeviceAndLink.addLocalDevice(recLsa, ospfInterface, ospfArea);
1129 callDeviceAndLinkAdding(topologyForDeviceAndLink);
1130 log.debug("Adding to lsdb interface State {}", ((OspfInterfaceImpl) ospfInterface).state().value());
1131 // should not send any acknowledge if flooded out on receiving interface
1132 if (((OspfInterfaceImpl) ospfInterface).state().value() == OspfInterfaceState.BDR.value()) {
1133 if (neighborDr.equals(sourceIp)) {
1134 log.debug("Adding for delayed ack {}", recLsa);
1135 ((OspfInterfaceImpl) ospfInterface).addLsaHeaderForDelayAck(recLsa);
1136 }
1137 } else {
1138 log.debug("Adding for delayed ack {}", recLsa);
1139 ((OspfInterfaceImpl) ospfInterface).addLsaHeaderForDelayAck(recLsa);
1140 }
1141
1142 if (((OspfInterfaceImpl) ospfInterface).state().value() == OspfInterfaceState.DR.value() ||
1143 ((OspfInterfaceImpl) ospfInterface).state().value() ==
1144 OspfInterfaceState.POINT2POINT.value()) {
1145 ((OspfAreaImpl) ospfArea).addToOtherNeighborLsaTxList(recLsa);
1146 }
1147 }
1148
1149 }
1150 }
1151 // RFC 2328 Section 13 (6)
1152 if (lsReqList.contains(key)) {
1153 badLSReq(ch);
1154 }
1155 if (status.equals("same")) { //13 (7)
1156 if (pendingReTxList.containsKey(key)) {
1157 pendingReTxList.remove(key);
1158 if (((OspfInterfaceImpl) ospfInterface).state().value() == OspfInterfaceState.BDR.value()) {
1159 if (neighborDr.equals(recLsa.advertisingRouter())) {
1160 ((OspfInterfaceImpl) ospfInterface).addLsaHeaderForDelayAck(recLsa);
1161 }
1162 }
1163 } else {
1164 directAcknowledge(recLsa, ch, sourceIp);
1165 return true;
1166 }
1167 } else if (status.equals("old")) { // section 13 - point 8
1168 if ((recLsa.lsSequenceNo() == OspfParameters.MAXSEQUENCENUMBER) &&
1169 (recLsa.age() == OspfParameters.MAXAGE)) {
1170 // section 13 - point 8
1171 // simple discard the received LSA -
1172 return true;
1173 } else {
1174 // respond back with the same LSA
1175 //Using flood LSA to sent the LSUpdate back to advertising router
1176 int diff = Math.abs(lsWrapper.lsaAgeReceived() - recLsa.age());
1177 if (diff > OspfParameters.MINLSARRIVAL) {
1178 sendLsa(((LsaWrapperImpl) lsWrapper).lsaHeader(), sourceIp, ch);
1179 }
1180 }
1181 }
1182 callDeviceAndLinkAdding(topologyForDeviceAndLink);
1183 return true;
1184 }
1185
1186 /**
1187 * Checks Link State ID is equal to one of the router's own IP interface addresses.
1188 *
1189 * @param linkStateId link state id
1190 * @return true if link state matches or false
1191 */
1192 private boolean isLinkStateMatchesOwnRouterId(String linkStateId) {
1193 boolean isLinkStateMatches = false;
1194 List<OspfInterface> interfaceLst = ospfArea.getInterfacesLst();
1195 for (OspfInterface ospfInterface : interfaceLst) {
1196 if (ospfInterface.ipAddress().toString().equals(linkStateId)) {
1197 isLinkStateMatches = true;
1198 break;
1199 }
1200 }
1201
1202 return isLinkStateMatches;
1203 }
1204
1205 /**
1206 * RFC 2328 Section 13 (5).
1207 *
1208 * @param lsWrapper ls wrapper instance
1209 * @param recLsa received LSA instance
1210 * @return returns a string status
1211 */
1212 public String isNullorLatest(LsaWrapper lsWrapper, LsaHeader recLsa) {
1213
1214
1215 if (lsWrapper != null) {
1216 LsaHeader ownLsa = (LsaHeader) lsWrapper.ospfLsa();
1217 String status = ospfArea.isNewerOrSameLsa(recLsa, ownLsa);
1218
1219 if (status.equals("latest")) {
1220 return "isNullorLatest";
1221 } else {
1222 return status;
1223 }
1224 } else {
1225 return "isNullorLatest";
1226 }
1227 }
1228
1229 /**
1230 * RFC 2328 section 13.4
1231 * Processing self-originated LSAs.
1232 *
1233 * @throws Exception might throws exception
1234 */
1235 public void processSelfOriginatedLsa() throws Exception {
1236 ospfArea.refreshArea(ospfInterface);
1237 }
1238
1239 /**
1240 * Sends the LSA to destination address.
1241 *
1242 * @param lsa LSA instance to sent
1243 * @param destination destination IP address
1244 * @param ch netty channel instance
1245 */
1246 public void sendLsa(LsaHeader lsa, Ip4Address destination, Channel ch) {
1247 if (lsa == null) {
1248 return;
1249 }
1250
1251 LsUpdate responseLsUpdate = new LsUpdate();
1252 // seting OSPF Header
1253 responseLsUpdate.setOspfVer(OspfUtil.OSPF_VERSION);
1254 responseLsUpdate.setOspftype(OspfPacketType.LSUPDATE.value());
1255 responseLsUpdate.setRouterId(ospfArea.routerId());
1256 responseLsUpdate.setAreaId(ospfArea.areaId());
1257 responseLsUpdate.setAuthType(OspfUtil.NOT_ASSIGNED);
1258 responseLsUpdate.setAuthentication(OspfUtil.NOT_ASSIGNED);
1259 responseLsUpdate.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
1260 responseLsUpdate.setChecksum(OspfUtil.NOT_ASSIGNED);
1261 responseLsUpdate.setNumberOfLsa(1);
1262 responseLsUpdate.addLsa(lsa);
1263
1264 //setting the destination.
1265 responseLsUpdate.setDestinationIp(destination);
1266 ch.write(responseLsUpdate);
1267 }
1268
1269 /**
1270 * Sends a direct Acknowledgment for a particular LSA to the Neighbor.
1271 *
1272 * @param ackLsa LSA instance
1273 * @param ch netty channel instance
1274 * @param sourceIp source IP address
1275 */
1276 public void directAcknowledge(LsaHeader ackLsa, Channel ch, Ip4Address sourceIp) {
1277 log.debug("OSPFNbr::directAcknowledge...!!!");
1278
1279 LsAcknowledge ackContent = new LsAcknowledge();
1280 // seting OSPF Header
1281 ackContent.setOspfVer(OspfUtil.OSPF_VERSION);
1282 ackContent.setOspftype(OspfPacketType.LSAACK.value());
1283 ackContent.setRouterId(ospfArea.routerId());
1284 ackContent.setAreaId(ospfArea.areaId());
1285 ackContent.setAuthType(OspfUtil.NOT_ASSIGNED);
1286 ackContent.setAuthentication(OspfUtil.NOT_ASSIGNED);
1287 ackContent.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
1288 ackContent.setChecksum(OspfUtil.NOT_ASSIGNED);
1289 ackContent.addLinkStateHeader(ackLsa);
1290 //setting the destination IP
1291 ackContent.setDestinationIp(sourceIp);
1292 ch.write(ackContent);
1293 }
1294
1295 /**
1296 * Called when neighbor is down.
1297 *
1298 * @throws Exception might throws exception
1299 */
1300 public void neighborDown() throws Exception {
1301 log.debug("Neighbor Down {} and NeighborId {}", neighborIpAddr,
1302 neighborId);
1303 stopInactivityTimeCheck();
1304 stopRxMtDdTimer();
1305 stopRxMtLsrTimer();
1306
1307 if (floodingTimerScheduled) {
1308 stopFloodingTimer();
1309 floodingTimerScheduled = false;
1310 }
1311
1312 state = OspfNeighborState.DOWN;
1313 ospfArea.refreshArea(ospfInterface);
1314 lsReqList.clear();
1315 ddSummaryList.clear();
1316 if (neighborIpAddr.equals(neighborBdr) ||
1317 neighborIpAddr.equals(neighborDr)) {
1318 handler.neighborChange();
1319 }
1320 log.debug("Neighbor Went Down : "
1321 + this.neighborIpAddr + " , " + this.neighborId);
1322 removeDeviceDetails(this.neighborId);
1323 OspfRouter ospfRouter = new OspfRouterImpl();
1324 ospfRouter.setRouterIp(this.neighborId());
1325 ospfRouter.setInterfaceId(ospfInterface.ipAddress());
1326 ospfRouter.setAreaIdOfInterface(ospfArea.areaId());
1327 ospfRouter.setDeviceTed(new OspfDeviceTedImpl());
1328 handler.removeDeviceInformation(ospfRouter);
1329 removeDeviceDetails(this.neighborIpAddr);
1330 OspfRouter ospfRouter1 = new OspfRouterImpl();
1331 ospfRouter1.setRouterIp(this.neighborIpAddr);
1332 ospfRouter1.setInterfaceId(ospfInterface.ipAddress());
1333 ospfRouter1.setAreaIdOfInterface(ospfArea.areaId());
1334 ospfRouter1.setDeviceTed(new OspfDeviceTedImpl());
1335 handler.removeDeviceInformation(ospfRouter1);
1336 handler.removeLinkInformation(this);
1337 callDeviceAndLinkAdding(topologyForDeviceAndLink);
1338 }
1339
1340 /**
1341 * Removes device details.
1342 *
1343 * @param routerId router id
1344 */
1345 private void removeDeviceDetails(Ip4Address routerId) {
1346 String key = "device:" + routerId;
1347 topologyForDeviceAndLink.removeDeviceInformationMap(key);
1348 topologyForDeviceAndLink.removeLinks(routerId);
1349 }
1350
1351 /**
1352 * Starts the inactivity timer.
1353 */
1354 private void startInactivityTimeCheck() {
1355 if (!inActivityTimerScheduled) {
1356 log.debug("OSPFNbr::startInactivityTimeCheck");
1357 inActivityTimeCheckTask = new InternalInactivityTimeCheck();
1358 exServiceInActivity = Executors.newSingleThreadScheduledExecutor();
1359 exServiceInActivity.scheduleAtFixedRate(inActivityTimeCheckTask, routerDeadInterval,
1360 routerDeadInterval, TimeUnit.SECONDS);
1361 inActivityTimerScheduled = true;
1362 }
1363 }
1364
1365 /**
1366 * Stops the inactivity timer.
1367 */
1368 private void stopInactivityTimeCheck() {
1369 if (inActivityTimerScheduled) {
1370 log.debug("OSPFNbr::stopInactivityTimeCheck ");
1371 exServiceInActivity.shutdown();
1372 inActivityTimerScheduled = false;
1373 }
1374 }
1375
1376 /**
1377 * Starts the flooding timer.
1378 *
1379 * @param channel channel instance
1380 */
1381 public void startFloodingTimer(Channel channel) {
1382
1383 if (!floodingTimerScheduled) {
1384 log.debug("OSPFNbr::startFloodingTimer");
1385 floodingTask = new InternalFloodingTask(channel);
1386 exServiceFlooding = Executors.newSingleThreadScheduledExecutor();
1387 //Run every 5 seconds.
1388 exServiceFlooding.scheduleAtFixedRate(floodingTask, OspfParameters.START_NOW,
1389 OspfParameters.MINLSINTERVAL, TimeUnit.SECONDS);
1390 floodingTimerScheduled = true;
1391 }
1392 }
1393
1394 /**
1395 * Stops the flooding timer.
1396 */
1397 private void stopFloodingTimer() {
1398 if (floodingTimerScheduled) {
1399 log.debug("OSPFNbr::stopFloodingTimer ");
1400 exServiceFlooding.shutdown();
1401 floodingTimerScheduled = false;
1402 }
1403 }
1404
1405 /**
1406 * Starts the Dd Retransmission executor task.
1407 *
1408 * @param ch netty channel instance
1409 */
1410 private void startRxMtDdTimer(Channel ch) {
1411 if (!rxmtDdPacketTimerScheduled) {
1412 long retransmitInterval = ospfInterface.reTransmitInterval();
1413 rxmtDdPacketTask = new InternalRxmtDdPacket(ch);
1414 exServiceRxmtDDPacket = Executors.newSingleThreadScheduledExecutor();
1415 exServiceRxmtDDPacket.scheduleAtFixedRate(rxmtDdPacketTask, retransmitInterval,
1416 retransmitInterval, TimeUnit.SECONDS);
1417 rxmtDdPacketTimerScheduled = true;
1418 }
1419 }
1420
1421 /**
1422 * Stops the Dd Retransmission executor task.
1423 */
1424 private void stopRxMtDdTimer() {
1425 if (rxmtDdPacketTimerScheduled) {
1426 exServiceRxmtDDPacket.shutdown();
1427 rxmtDdPacketTimerScheduled = false;
1428 }
1429 }
1430
1431 /**
1432 * Starts Ls request retransmission executor task.
1433 *
1434 * @param ch Netty channel instance
1435 */
1436 private void startRxMtLsrTimer(Channel ch) {
1437 if (!rxmtLsrTimerScheduled) {
1438 log.debug("OSPFNbr::startRxMtLsrTimer...!!!");
1439 long retransmitIntrvl = ospfInterface.reTransmitInterval();
1440 rxmtLsrPacketTask = new InternalRxmtLsrPacket(ch);
1441 exServiceRxmtLsr = Executors.newSingleThreadScheduledExecutor();
1442 exServiceRxmtLsr.scheduleAtFixedRate(rxmtLsrPacketTask, retransmitIntrvl,
1443 retransmitIntrvl, TimeUnit.SECONDS);
1444 rxmtLsrTimerScheduled = true;
1445 }
1446 }
1447
1448 /**
1449 * Stops Ls request retransmission executor task.
1450 */
1451 private void stopRxMtLsrTimer() {
1452 if (rxmtLsrTimerScheduled) {
1453 exServiceRxmtLsr.shutdown();
1454 rxmtLsrTimerScheduled = false;
1455 }
1456 }
1457
1458 /**
1459 * Gets the last sent DdPacket.
1460 *
1461 * @return DdPacket instance
1462 */
1463 public DdPacket lastDdPacket() {
1464 return lastDdPacket;
1465 }
1466
1467 /**
1468 * Sets the last sent DdPacket.
1469 *
1470 * @param lastDdPacket DdPacket instance
1471 */
1472 public void setLastDdPacket(DdPacket lastDdPacket) {
1473 this.lastDdPacket = lastDdPacket;
1474 }
1475
1476 /**
1477 * Gets neighbor id.
1478 *
1479 * @return neighbor id
1480 */
1481 public Ip4Address neighborId() {
1482 return neighborId;
1483 }
1484
1485 /**
1486 * Sets the neighbor id.
1487 *
1488 * @param neighborId neighbor id
1489 */
1490 public void setNeighborId(Ip4Address neighborId) {
1491 this.neighborId = neighborId;
1492 }
1493
1494 /**
1495 * Gets the neighbor DR address.
1496 *
1497 * @return neighbor DR address
1498 */
1499 public Ip4Address neighborDr() {
1500 return neighborDr;
1501 }
1502
1503 /**
1504 * Sets the neighbor DR address.
1505 *
1506 * @param neighborDr neighbor DR address
1507 */
1508 public void setNeighborDr(Ip4Address neighborDr) {
1509 this.neighborDr = neighborDr;
1510 }
1511
1512 /**
1513 * Gets the neighbor BDR address.
1514 *
1515 * @return neighbor BDR address
1516 */
1517 public Ip4Address neighborBdr() {
1518 return neighborBdr;
1519 }
1520
1521 /**
1522 * Sets the neighbor BDR address.
1523 *
1524 * @param neighborBdr neighbor BDR address
1525 */
1526 public void setNeighborBdr(Ip4Address neighborBdr) {
1527 this.neighborBdr = neighborBdr;
1528 }
1529
1530 /**
1531 * Gets router priority.
1532 *
1533 * @return router priority
1534 */
1535 public int routerPriority() {
1536 return routerPriority;
1537 }
1538
1539 /**
1540 * Sets router priority.
1541 *
1542 * @param routerPriority router priority
1543 */
1544 public void setRouterPriority(int routerPriority) {
1545 this.routerPriority = routerPriority;
1546 }
1547
1548 /**
1549 * Gets the options value.
1550 *
1551 * @return options value
1552 */
1553 public int options() {
1554 return options;
1555 }
1556
1557 /**
1558 * Sets the options value.
1559 *
1560 * @param options options value
1561 */
1562 public void setOptions(int options) {
1563 this.options = options;
1564 }
1565
1566 /**
1567 * Gets the DD sequence number.
1568 *
1569 * @return DD sequence number
1570 */
1571 public long ddSeqNum() {
1572 return ddSeqNum;
1573 }
1574
1575 /**
1576 * Sets the DD sequence number.
1577 *
1578 * @param ddSeqNum DD sequence number
1579 */
1580 public void setDdSeqNum(long ddSeqNum) {
1581 this.ddSeqNum = ddSeqNum;
1582 }
1583
1584 /**
1585 * Gets neighbor is master or not.
1586 *
1587 * @return true if neighbor is master else false
1588 */
1589 public int isMaster() {
1590 return isMaster;
1591 }
1592
1593 /**
1594 * Gets the last sent DD Packet.
1595 *
1596 * @return last sent DD Packet
1597 */
1598 public DdPacket lastSentDdPacket() {
1599 return lastSentDdPacket;
1600 }
1601
1602 /**
1603 * Sets the last sent DD Packet.
1604 *
1605 * @param lastSentDdPacket last sent DD Packet
1606 */
1607 public void setLastSentDdPacket(DdPacket lastSentDdPacket) {
1608 this.lastSentDdPacket = lastSentDdPacket;
1609 }
1610
1611 /**
1612 * Gets the last sent Ls Request Packet.
1613 *
1614 * @return last sent Ls Request Packet
1615 */
1616 public LsRequest getLastSentLsrPacket() {
1617 return lastSentLsrPacket;
1618 }
1619
1620 /**
1621 * Sets the last sent Ls Request Packet.
1622 *
1623 * @param lastSentLsrPacket last sent Ls Request Packet
1624 */
1625 public void setLastSentLsrPacket(LsRequest lastSentLsrPacket) {
1626 this.lastSentLsrPacket = lastSentLsrPacket;
1627 }
1628
1629 /**
1630 * Gets the neighbors state.
1631 *
1632 * @return neighbors state
1633 */
1634 public OspfNeighborState getState() {
1635 return state;
1636 }
1637
1638 /**
1639 * Sets the neighbors state.
1640 *
1641 * @param state neighbors state
1642 */
1643 public void setState(OspfNeighborState state) {
1644 this.state = state;
1645 }
1646
1647 /**
1648 * Sets neighbor is master or not.
1649 *
1650 * @param isMaster neighbor is master or not
1651 */
1652 public void setIsMaster(int isMaster) {
1653 this.isMaster = isMaster;
1654 }
1655
1656 /**
1657 * Gets the ls request list.
1658 *
1659 * @return ls request list
1660 */
1661 public Hashtable getLsReqList() {
1662 return lsReqList;
1663 }
1664
1665 /**
1666 * Gets the reTxList instance.
1667 *
1668 * @return reTxList instance
1669 */
1670 public Map getReTxList() {
1671 return reTxList;
1672 }
1673
1674 /**
1675 * Gets the pending re transmit list.
1676 *
1677 * @return pendingReTxList instance
1678 */
1679 public Map<String, OspfLsa> getPendingReTxList() {
1680 return pendingReTxList;
1681 }
1682
1683
1684 /**
1685 * Represents a Task which will do an inactivity time check.
1686 */
1687 private class InternalInactivityTimeCheck implements Runnable {
1688 /**
1689 * Constructor.
1690 */
1691 InternalInactivityTimeCheck() {
1692 }
1693
1694 @Override
1695 public void run() {
1696 try {
1697 log.debug("Neighbor Not Heard till the past router dead interval .");
1698 neighborDown();
1699 } catch (Exception e) {
1700 log.debug("Exception at inactivity time check...!!!");
1701 }
1702 }
1703 }
1704
1705 /**
1706 * Task which re transmits DdPacket every configured time interval.
1707 */
1708 private class InternalRxmtDdPacket implements Runnable {
1709 Channel ch;
1710
1711 /**
1712 * Creates an instance or Re transmit DD packet timer.
1713 *
1714 * @param ch netty channel instance
1715 */
1716 InternalRxmtDdPacket(Channel ch) {
1717 this.ch = ch;
1718 }
1719
1720 @Override
1721 public void run() {
1722 if ((ch != null) && ch.isConnected()) {
1723 DdPacket ddPacket = lastSentDdPacket();
1724 ch.write(ddPacket);
1725 log.debug("Re-Transmit DD Packet .");
1726 } else {
1727 log.debug(
1728 "Re-Transmit DD Packet failed. Channel not connected..");
1729 }
1730 }
1731 }
1732
1733 /**
1734 * Task which re transmits Ls request Packet every configured time interval.
1735 */
1736 private class InternalRxmtLsrPacket implements Runnable {
1737 Channel ch;
1738
1739 /**
1740 * Creates an instance or Re transmit LS Request packet timer.
1741 *
1742 * @param ch netty channel instance
1743 */
1744 InternalRxmtLsrPacket(Channel ch) {
1745 this.ch = ch;
1746 }
1747
1748 @Override
1749 public void run() {
1750 if ((ch != null) && ch.isConnected()) {
1751 LsRequest lsrPacket = getLastSentLsrPacket();
1752 ch.write(lsrPacket);
1753 log.debug("Re-Transmit LSRequest Packet .");
1754 } else {
1755 log.debug(
1756 "Re-Transmit LSRequest failed. Channel not connected..");
1757 }
1758 }
1759 }
1760
1761 /**
1762 * Task which transmits Ls update Packet based on the re transmit list.
1763 * every configured time interval.
1764 */
1765 private class InternalFloodingTask implements Runnable {
1766 Channel channel;
1767
1768 /**
1769 * Creates an instance or Flooding task.
1770 *
1771 * @param ch netty channel instance
1772 */
1773 InternalFloodingTask(Channel ch) {
1774 this.channel = ch;
1775 }
1776
1777 @Override
1778 public void run() {
1779 if ((channel != null) && channel.isConnected()) {
1780
1781 if ((pendingReTxList != null) && (pendingReTxList.size() > 0)) {
1782 List<LsUpdate> lsUpdateList = buildLsUpdate(pendingReTxList);
1783
1784 for (LsUpdate lsupdate : lsUpdateList) {
1785 //Pending for acknowledge directly sent it to neighbor
1786 lsupdate.setDestinationIp(neighborIpAddr);
1787 channel.write(lsupdate);
1788 }
1789 }
1790
1791 if ((reTxList != null) && (reTxList.size() > 0)) {
1792 List<LsUpdate> lsUpdateList = buildLsUpdate(reTxList);
1793
1794 for (LsUpdate lsupdate : lsUpdateList) {
1795 //set the destination
1796 if ((((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.DR) ||
1797 (((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.POINT2POINT)) {
1798 lsupdate.setDestinationIp(OspfUtil.ALL_SPF_ROUTERS);
1799 } else if (((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.DROTHER ||
1800 (((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.BDR)) {
1801 lsupdate.setDestinationIp(neighborDr);
1802 }
1803 channel.write(lsupdate);
1804 }
1805 }
1806 }
1807 }
1808
1809 /**
1810 * Builds the LsUpdate for flooding.
1811 *
1812 * @param txList list contains LSAs
1813 * @return list of LsUpdate instances
1814 */
1815 private List buildLsUpdate(Map<String, OspfLsa> txList) {
1816 List<LsUpdate> lsUpdateList = new ArrayList<>();
1817 ListIterator itr = new ArrayList(txList.keySet()).listIterator();
1818 while (itr.hasNext()) {
1819 LsUpdate lsupdate = new LsUpdate();
1820 // seting OSPF Header
1821 lsupdate.setOspfVer(OspfUtil.OSPF_VERSION);
1822 lsupdate.setOspftype(OspfPacketType.LSUPDATE.value());
1823 lsupdate.setRouterId(ospfArea.routerId());
1824 lsupdate.setAreaId(ospfArea.areaId());
1825 lsupdate.setAuthType(OspfUtil.NOT_ASSIGNED);
1826 lsupdate.setAuthentication(OspfUtil.NOT_ASSIGNED);
1827 lsupdate.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
1828 lsupdate.setChecksum(OspfUtil.NOT_ASSIGNED);
1829
1830 //limit to mtu
1831 int currentLength = OspfUtil.OSPF_HEADER_LENGTH + OspfUtil.FOUR_BYTES;
1832 int maxSize = ospfInterface.mtu() -
1833 OspfUtil.LSA_HEADER_LENGTH; // subtract a normal IP header.
1834
1835 int noLsa = 0;
1836 while (itr.hasNext()) {
1837
1838 String key = (String) itr.next();
1839 OspfLsa lsa = txList.get(key);
1840 if ((lsa.age() + OspfParameters.INFTRA_NS_DELAY) >= OspfParameters.MAXAGE) {
1841 ((LsaHeader) lsa.lsaHeader()).setAge(OspfParameters.MAXAGE);
1842 } else {
1843 ((LsaHeader) lsa.lsaHeader()).setAge(lsa.age() + OspfParameters.INFTRA_NS_DELAY);
1844 }
1845
1846 if ((currentLength + ((LsaHeader) lsa.lsaHeader()).lsPacketLen()) >= maxSize) {
1847 itr.previous();
1848 break;
1849 }
1850 log.debug("FloodingTimer::LSA Type::{}, Header: {}, LSA: {}", lsa.getOspfLsaType(),
1851 lsa.lsaHeader(), lsa);
1852
1853 if (lsa != null) {
1854 lsupdate.addLsa(lsa);
1855 noLsa++;
1856 currentLength = currentLength + ((LsaHeader) lsa.lsaHeader()).lsPacketLen();
1857 }
1858 log.debug("FloodingTimer::Removing key {}", key);
1859 if (txList.equals(reTxList)) {
1860 reTxList.remove(key);
1861 pendingReTxList.put(key, lsa);
1862 }
1863 }
1864 //set number of lsa's
1865 lsupdate.setNumberOfLsa(noLsa);
1866 lsUpdateList.add(lsupdate);
1867 }
1868 return lsUpdateList;
1869 }
1870 }
1871}