blob: 1233c285f92acee82cef84d3478eb877aa2f8905 [file] [log] [blame]
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002* Copyright 2016-present Open Networking Laboratory
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05303*
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) &&
sunish vkaa48da82016-03-02 23:17:06 +05301049 (!ospfArea.isExternalRoutingCapability())) {
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301050 return true;
1051 }
1052
1053 //if lsa age is equal to maxage && instance is not in lsdb && none of neighbors are in exchange
1054 // or loading state
1055 // Acknowledge the receipt by sending LSAck to the sender. 2328 13(4)
1056 if ((recLsa.age() == OspfParameters.MAXAGE) &&
1057 (ospfArea.lsaLookup(recLsa) == null) &&
1058 ospfArea.noNeighborInLsaExchangeProcess()) {
1059 // RFC 2328 Section 13. (4)
1060 // Because the LSA was not yet requested, it is treated as a flooded LSA and thus
1061 // acknowledged.
1062 directAcknowledge(recLsa, ch, sourceIp);
1063 return true;
1064 }
1065
1066 String key = ((OspfAreaImpl) ospfArea).getLsaKey(recLsa);
1067 LsaWrapper lsWrapper = ospfArea.lsaLookup(recLsa);
1068 String status = isNullorLatest(lsWrapper, recLsa);
1069 //Section 13 (5)
1070 if (status.equals("isNullorLatest")) {
1071
1072 if (recLsa.lsType() == OspfLsaType.ROUTER.value() && recLsa.advertisingRouter().equals(
1073 ospfArea.routerId())) {
1074 if (recLsa.lsSequenceNo() > ((LsaWrapperImpl) lsWrapper).lsaHeader().lsSequenceNo()) {
1075 ospfArea.setDbRouterSequenceNumber(recLsa.lsSequenceNo() + 1);
1076 processSelfOriginatedLsa();
1077 }
1078
1079 if (recLsa.age() == OspfParameters.MAXAGE) {
1080 ((LsaWrapperImpl) lsWrapper).lsaHeader().setAge(OspfParameters.MAXAGE);
1081 //remove from db & bin, add the lsa to MaxAge bin.
1082 ospfArea.addLsaToMaxAgeBin(((OspfAreaImpl) ospfArea).getLsaKey(((LsaWrapperImpl)
1083 lsWrapper).lsaHeader()), lsWrapper);
1084 ospfArea.removeLsaFromBin(lsWrapper);
1085 }
1086
1087 return true;
1088 } else if (recLsa.lsType() == OspfLsaType.NETWORK.value() && isLinkStateMatchesOwnRouterId(
1089 recLsa.linkStateId())) {
1090 // if we are not DR or if origination router ID not equal to our router ID //either
1091 // DR state changed or our router ID was changed
1092 //set LSAge = MaxAge
1093 //flood the LSA
1094 if (((OspfInterfaceImpl) ospfInterface).state() != OspfInterfaceState.DR ||
1095 !recLsa.advertisingRouter().equals(
1096 ospfArea.routerId())) {
1097 if (lsWrapper != null) {
1098 ((LsaWrapperImpl) lsWrapper).lsaHeader().setAge(OspfParameters.MAXAGE);
1099 //remove from bin, add the lsa to MaxAge bin.
1100 ospfArea.addLsaToMaxAgeBin(((OspfAreaImpl) ospfArea).getLsaKey(((LsaWrapperImpl)
1101 lsWrapper).lsaHeader()), lsWrapper);
1102 ospfArea.removeLsaFromBin(lsWrapper);
1103 } else {
1104 recLsa.setAge(OspfParameters.MAXAGE);
1105 ((OspfAreaImpl) ospfArea).addToOtherNeighborLsaTxList(recLsa);
1106 }
1107 }
1108
1109 return true;
1110 } else {
1111 if (recLsa.age() == OspfParameters.MAXAGE) {
1112 ((OspfInterfaceImpl) ospfInterface).addLsaHeaderForDelayAck(recLsa);
1113 //remove from db & bin, add the lsa to MaxAge bin.
1114 if (lsWrapper != null) {
1115 lsWrapper.setLsaAgeReceived(OspfParameters.MAXAGE);
1116 ospfArea.addLsaToMaxAgeBin(((OspfAreaImpl) ospfArea).getLsaKey(((LsaWrapperImpl)
1117 lsWrapper).lsaHeader()), lsWrapper);
1118 ospfArea.removeLsaFromBin(lsWrapper);
1119 } else {
1120 ((OspfAreaImpl) ospfArea).addToOtherNeighborLsaTxList(recLsa);
1121 }
1122
1123 return true;
1124 } else {
1125 ospfArea.addLsa(recLsa, ospfInterface);
1126 log.debug("Inside addLsaMethod");
1127 topologyForDeviceAndLink.addLocalDevice(recLsa, ospfInterface, ospfArea);
1128 callDeviceAndLinkAdding(topologyForDeviceAndLink);
1129 log.debug("Adding to lsdb interface State {}", ((OspfInterfaceImpl) ospfInterface).state().value());
1130 // should not send any acknowledge if flooded out on receiving interface
1131 if (((OspfInterfaceImpl) ospfInterface).state().value() == OspfInterfaceState.BDR.value()) {
1132 if (neighborDr.equals(sourceIp)) {
1133 log.debug("Adding for delayed ack {}", recLsa);
1134 ((OspfInterfaceImpl) ospfInterface).addLsaHeaderForDelayAck(recLsa);
1135 }
1136 } else {
1137 log.debug("Adding for delayed ack {}", recLsa);
1138 ((OspfInterfaceImpl) ospfInterface).addLsaHeaderForDelayAck(recLsa);
1139 }
1140
1141 if (((OspfInterfaceImpl) ospfInterface).state().value() == OspfInterfaceState.DR.value() ||
1142 ((OspfInterfaceImpl) ospfInterface).state().value() ==
1143 OspfInterfaceState.POINT2POINT.value()) {
1144 ((OspfAreaImpl) ospfArea).addToOtherNeighborLsaTxList(recLsa);
1145 }
1146 }
1147
1148 }
1149 }
1150 // RFC 2328 Section 13 (6)
1151 if (lsReqList.contains(key)) {
1152 badLSReq(ch);
1153 }
1154 if (status.equals("same")) { //13 (7)
1155 if (pendingReTxList.containsKey(key)) {
1156 pendingReTxList.remove(key);
1157 if (((OspfInterfaceImpl) ospfInterface).state().value() == OspfInterfaceState.BDR.value()) {
1158 if (neighborDr.equals(recLsa.advertisingRouter())) {
1159 ((OspfInterfaceImpl) ospfInterface).addLsaHeaderForDelayAck(recLsa);
1160 }
1161 }
1162 } else {
1163 directAcknowledge(recLsa, ch, sourceIp);
1164 return true;
1165 }
1166 } else if (status.equals("old")) { // section 13 - point 8
1167 if ((recLsa.lsSequenceNo() == OspfParameters.MAXSEQUENCENUMBER) &&
1168 (recLsa.age() == OspfParameters.MAXAGE)) {
1169 // section 13 - point 8
1170 // simple discard the received LSA -
1171 return true;
1172 } else {
1173 // respond back with the same LSA
1174 //Using flood LSA to sent the LSUpdate back to advertising router
1175 int diff = Math.abs(lsWrapper.lsaAgeReceived() - recLsa.age());
1176 if (diff > OspfParameters.MINLSARRIVAL) {
1177 sendLsa(((LsaWrapperImpl) lsWrapper).lsaHeader(), sourceIp, ch);
1178 }
1179 }
1180 }
1181 callDeviceAndLinkAdding(topologyForDeviceAndLink);
1182 return true;
1183 }
1184
1185 /**
1186 * Checks Link State ID is equal to one of the router's own IP interface addresses.
1187 *
1188 * @param linkStateId link state id
1189 * @return true if link state matches or false
1190 */
1191 private boolean isLinkStateMatchesOwnRouterId(String linkStateId) {
1192 boolean isLinkStateMatches = false;
1193 List<OspfInterface> interfaceLst = ospfArea.getInterfacesLst();
1194 for (OspfInterface ospfInterface : interfaceLst) {
1195 if (ospfInterface.ipAddress().toString().equals(linkStateId)) {
1196 isLinkStateMatches = true;
1197 break;
1198 }
1199 }
1200
1201 return isLinkStateMatches;
1202 }
1203
1204 /**
1205 * RFC 2328 Section 13 (5).
1206 *
1207 * @param lsWrapper ls wrapper instance
1208 * @param recLsa received LSA instance
1209 * @return returns a string status
1210 */
1211 public String isNullorLatest(LsaWrapper lsWrapper, LsaHeader recLsa) {
1212
1213
1214 if (lsWrapper != null) {
1215 LsaHeader ownLsa = (LsaHeader) lsWrapper.ospfLsa();
1216 String status = ospfArea.isNewerOrSameLsa(recLsa, ownLsa);
1217
1218 if (status.equals("latest")) {
1219 return "isNullorLatest";
1220 } else {
1221 return status;
1222 }
1223 } else {
1224 return "isNullorLatest";
1225 }
1226 }
1227
1228 /**
1229 * RFC 2328 section 13.4
1230 * Processing self-originated LSAs.
1231 *
1232 * @throws Exception might throws exception
1233 */
1234 public void processSelfOriginatedLsa() throws Exception {
1235 ospfArea.refreshArea(ospfInterface);
1236 }
1237
1238 /**
1239 * Sends the LSA to destination address.
1240 *
1241 * @param lsa LSA instance to sent
1242 * @param destination destination IP address
1243 * @param ch netty channel instance
1244 */
1245 public void sendLsa(LsaHeader lsa, Ip4Address destination, Channel ch) {
1246 if (lsa == null) {
1247 return;
1248 }
1249
1250 LsUpdate responseLsUpdate = new LsUpdate();
1251 // seting OSPF Header
1252 responseLsUpdate.setOspfVer(OspfUtil.OSPF_VERSION);
1253 responseLsUpdate.setOspftype(OspfPacketType.LSUPDATE.value());
1254 responseLsUpdate.setRouterId(ospfArea.routerId());
1255 responseLsUpdate.setAreaId(ospfArea.areaId());
1256 responseLsUpdate.setAuthType(OspfUtil.NOT_ASSIGNED);
1257 responseLsUpdate.setAuthentication(OspfUtil.NOT_ASSIGNED);
1258 responseLsUpdate.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
1259 responseLsUpdate.setChecksum(OspfUtil.NOT_ASSIGNED);
1260 responseLsUpdate.setNumberOfLsa(1);
1261 responseLsUpdate.addLsa(lsa);
1262
1263 //setting the destination.
1264 responseLsUpdate.setDestinationIp(destination);
1265 ch.write(responseLsUpdate);
1266 }
1267
1268 /**
1269 * Sends a direct Acknowledgment for a particular LSA to the Neighbor.
1270 *
1271 * @param ackLsa LSA instance
1272 * @param ch netty channel instance
1273 * @param sourceIp source IP address
1274 */
1275 public void directAcknowledge(LsaHeader ackLsa, Channel ch, Ip4Address sourceIp) {
1276 log.debug("OSPFNbr::directAcknowledge...!!!");
1277
1278 LsAcknowledge ackContent = new LsAcknowledge();
1279 // seting OSPF Header
1280 ackContent.setOspfVer(OspfUtil.OSPF_VERSION);
1281 ackContent.setOspftype(OspfPacketType.LSAACK.value());
1282 ackContent.setRouterId(ospfArea.routerId());
1283 ackContent.setAreaId(ospfArea.areaId());
1284 ackContent.setAuthType(OspfUtil.NOT_ASSIGNED);
1285 ackContent.setAuthentication(OspfUtil.NOT_ASSIGNED);
1286 ackContent.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
1287 ackContent.setChecksum(OspfUtil.NOT_ASSIGNED);
1288 ackContent.addLinkStateHeader(ackLsa);
1289 //setting the destination IP
1290 ackContent.setDestinationIp(sourceIp);
1291 ch.write(ackContent);
1292 }
1293
1294 /**
1295 * Called when neighbor is down.
1296 *
1297 * @throws Exception might throws exception
1298 */
1299 public void neighborDown() throws Exception {
1300 log.debug("Neighbor Down {} and NeighborId {}", neighborIpAddr,
1301 neighborId);
1302 stopInactivityTimeCheck();
1303 stopRxMtDdTimer();
1304 stopRxMtLsrTimer();
1305
1306 if (floodingTimerScheduled) {
1307 stopFloodingTimer();
1308 floodingTimerScheduled = false;
1309 }
1310
1311 state = OspfNeighborState.DOWN;
1312 ospfArea.refreshArea(ospfInterface);
1313 lsReqList.clear();
1314 ddSummaryList.clear();
1315 if (neighborIpAddr.equals(neighborBdr) ||
1316 neighborIpAddr.equals(neighborDr)) {
1317 handler.neighborChange();
1318 }
1319 log.debug("Neighbor Went Down : "
1320 + this.neighborIpAddr + " , " + this.neighborId);
1321 removeDeviceDetails(this.neighborId);
1322 OspfRouter ospfRouter = new OspfRouterImpl();
1323 ospfRouter.setRouterIp(this.neighborId());
1324 ospfRouter.setInterfaceId(ospfInterface.ipAddress());
1325 ospfRouter.setAreaIdOfInterface(ospfArea.areaId());
1326 ospfRouter.setDeviceTed(new OspfDeviceTedImpl());
1327 handler.removeDeviceInformation(ospfRouter);
1328 removeDeviceDetails(this.neighborIpAddr);
1329 OspfRouter ospfRouter1 = new OspfRouterImpl();
1330 ospfRouter1.setRouterIp(this.neighborIpAddr);
1331 ospfRouter1.setInterfaceId(ospfInterface.ipAddress());
1332 ospfRouter1.setAreaIdOfInterface(ospfArea.areaId());
1333 ospfRouter1.setDeviceTed(new OspfDeviceTedImpl());
1334 handler.removeDeviceInformation(ospfRouter1);
1335 handler.removeLinkInformation(this);
1336 callDeviceAndLinkAdding(topologyForDeviceAndLink);
1337 }
1338
1339 /**
1340 * Removes device details.
1341 *
1342 * @param routerId router id
1343 */
1344 private void removeDeviceDetails(Ip4Address routerId) {
1345 String key = "device:" + routerId;
1346 topologyForDeviceAndLink.removeDeviceInformationMap(key);
1347 topologyForDeviceAndLink.removeLinks(routerId);
1348 }
1349
1350 /**
1351 * Starts the inactivity timer.
1352 */
1353 private void startInactivityTimeCheck() {
1354 if (!inActivityTimerScheduled) {
1355 log.debug("OSPFNbr::startInactivityTimeCheck");
1356 inActivityTimeCheckTask = new InternalInactivityTimeCheck();
1357 exServiceInActivity = Executors.newSingleThreadScheduledExecutor();
1358 exServiceInActivity.scheduleAtFixedRate(inActivityTimeCheckTask, routerDeadInterval,
1359 routerDeadInterval, TimeUnit.SECONDS);
1360 inActivityTimerScheduled = true;
1361 }
1362 }
1363
1364 /**
1365 * Stops the inactivity timer.
1366 */
1367 private void stopInactivityTimeCheck() {
1368 if (inActivityTimerScheduled) {
1369 log.debug("OSPFNbr::stopInactivityTimeCheck ");
1370 exServiceInActivity.shutdown();
1371 inActivityTimerScheduled = false;
1372 }
1373 }
1374
1375 /**
1376 * Starts the flooding timer.
1377 *
1378 * @param channel channel instance
1379 */
1380 public void startFloodingTimer(Channel channel) {
1381
1382 if (!floodingTimerScheduled) {
1383 log.debug("OSPFNbr::startFloodingTimer");
1384 floodingTask = new InternalFloodingTask(channel);
1385 exServiceFlooding = Executors.newSingleThreadScheduledExecutor();
1386 //Run every 5 seconds.
1387 exServiceFlooding.scheduleAtFixedRate(floodingTask, OspfParameters.START_NOW,
1388 OspfParameters.MINLSINTERVAL, TimeUnit.SECONDS);
1389 floodingTimerScheduled = true;
1390 }
1391 }
1392
1393 /**
1394 * Stops the flooding timer.
1395 */
1396 private void stopFloodingTimer() {
1397 if (floodingTimerScheduled) {
1398 log.debug("OSPFNbr::stopFloodingTimer ");
1399 exServiceFlooding.shutdown();
1400 floodingTimerScheduled = false;
1401 }
1402 }
1403
1404 /**
1405 * Starts the Dd Retransmission executor task.
1406 *
1407 * @param ch netty channel instance
1408 */
1409 private void startRxMtDdTimer(Channel ch) {
1410 if (!rxmtDdPacketTimerScheduled) {
1411 long retransmitInterval = ospfInterface.reTransmitInterval();
1412 rxmtDdPacketTask = new InternalRxmtDdPacket(ch);
1413 exServiceRxmtDDPacket = Executors.newSingleThreadScheduledExecutor();
1414 exServiceRxmtDDPacket.scheduleAtFixedRate(rxmtDdPacketTask, retransmitInterval,
1415 retransmitInterval, TimeUnit.SECONDS);
1416 rxmtDdPacketTimerScheduled = true;
1417 }
1418 }
1419
1420 /**
1421 * Stops the Dd Retransmission executor task.
1422 */
1423 private void stopRxMtDdTimer() {
1424 if (rxmtDdPacketTimerScheduled) {
1425 exServiceRxmtDDPacket.shutdown();
1426 rxmtDdPacketTimerScheduled = false;
1427 }
1428 }
1429
1430 /**
1431 * Starts Ls request retransmission executor task.
1432 *
1433 * @param ch Netty channel instance
1434 */
1435 private void startRxMtLsrTimer(Channel ch) {
1436 if (!rxmtLsrTimerScheduled) {
1437 log.debug("OSPFNbr::startRxMtLsrTimer...!!!");
1438 long retransmitIntrvl = ospfInterface.reTransmitInterval();
1439 rxmtLsrPacketTask = new InternalRxmtLsrPacket(ch);
1440 exServiceRxmtLsr = Executors.newSingleThreadScheduledExecutor();
1441 exServiceRxmtLsr.scheduleAtFixedRate(rxmtLsrPacketTask, retransmitIntrvl,
1442 retransmitIntrvl, TimeUnit.SECONDS);
1443 rxmtLsrTimerScheduled = true;
1444 }
1445 }
1446
1447 /**
1448 * Stops Ls request retransmission executor task.
1449 */
1450 private void stopRxMtLsrTimer() {
1451 if (rxmtLsrTimerScheduled) {
1452 exServiceRxmtLsr.shutdown();
1453 rxmtLsrTimerScheduled = false;
1454 }
1455 }
1456
1457 /**
1458 * Gets the last sent DdPacket.
1459 *
1460 * @return DdPacket instance
1461 */
1462 public DdPacket lastDdPacket() {
1463 return lastDdPacket;
1464 }
1465
1466 /**
1467 * Sets the last sent DdPacket.
1468 *
1469 * @param lastDdPacket DdPacket instance
1470 */
1471 public void setLastDdPacket(DdPacket lastDdPacket) {
1472 this.lastDdPacket = lastDdPacket;
1473 }
1474
1475 /**
1476 * Gets neighbor id.
1477 *
1478 * @return neighbor id
1479 */
1480 public Ip4Address neighborId() {
1481 return neighborId;
1482 }
1483
1484 /**
1485 * Sets the neighbor id.
1486 *
1487 * @param neighborId neighbor id
1488 */
1489 public void setNeighborId(Ip4Address neighborId) {
1490 this.neighborId = neighborId;
1491 }
1492
1493 /**
1494 * Gets the neighbor DR address.
1495 *
1496 * @return neighbor DR address
1497 */
1498 public Ip4Address neighborDr() {
1499 return neighborDr;
1500 }
1501
1502 /**
1503 * Sets the neighbor DR address.
1504 *
1505 * @param neighborDr neighbor DR address
1506 */
1507 public void setNeighborDr(Ip4Address neighborDr) {
1508 this.neighborDr = neighborDr;
1509 }
1510
1511 /**
1512 * Gets the neighbor BDR address.
1513 *
1514 * @return neighbor BDR address
1515 */
1516 public Ip4Address neighborBdr() {
1517 return neighborBdr;
1518 }
1519
1520 /**
1521 * Sets the neighbor BDR address.
1522 *
1523 * @param neighborBdr neighbor BDR address
1524 */
1525 public void setNeighborBdr(Ip4Address neighborBdr) {
1526 this.neighborBdr = neighborBdr;
1527 }
1528
1529 /**
1530 * Gets router priority.
1531 *
1532 * @return router priority
1533 */
1534 public int routerPriority() {
1535 return routerPriority;
1536 }
1537
1538 /**
1539 * Sets router priority.
1540 *
1541 * @param routerPriority router priority
1542 */
1543 public void setRouterPriority(int routerPriority) {
1544 this.routerPriority = routerPriority;
1545 }
1546
1547 /**
1548 * Gets the options value.
1549 *
1550 * @return options value
1551 */
1552 public int options() {
1553 return options;
1554 }
1555
1556 /**
1557 * Sets the options value.
1558 *
1559 * @param options options value
1560 */
1561 public void setOptions(int options) {
1562 this.options = options;
1563 }
1564
1565 /**
1566 * Gets the DD sequence number.
1567 *
1568 * @return DD sequence number
1569 */
1570 public long ddSeqNum() {
1571 return ddSeqNum;
1572 }
1573
1574 /**
1575 * Sets the DD sequence number.
1576 *
1577 * @param ddSeqNum DD sequence number
1578 */
1579 public void setDdSeqNum(long ddSeqNum) {
1580 this.ddSeqNum = ddSeqNum;
1581 }
1582
1583 /**
1584 * Gets neighbor is master or not.
1585 *
1586 * @return true if neighbor is master else false
1587 */
1588 public int isMaster() {
1589 return isMaster;
1590 }
1591
1592 /**
1593 * Gets the last sent DD Packet.
1594 *
1595 * @return last sent DD Packet
1596 */
1597 public DdPacket lastSentDdPacket() {
1598 return lastSentDdPacket;
1599 }
1600
1601 /**
1602 * Sets the last sent DD Packet.
1603 *
1604 * @param lastSentDdPacket last sent DD Packet
1605 */
1606 public void setLastSentDdPacket(DdPacket lastSentDdPacket) {
1607 this.lastSentDdPacket = lastSentDdPacket;
1608 }
1609
1610 /**
1611 * Gets the last sent Ls Request Packet.
1612 *
1613 * @return last sent Ls Request Packet
1614 */
1615 public LsRequest getLastSentLsrPacket() {
1616 return lastSentLsrPacket;
1617 }
1618
1619 /**
1620 * Sets the last sent Ls Request Packet.
1621 *
1622 * @param lastSentLsrPacket last sent Ls Request Packet
1623 */
1624 public void setLastSentLsrPacket(LsRequest lastSentLsrPacket) {
1625 this.lastSentLsrPacket = lastSentLsrPacket;
1626 }
1627
1628 /**
1629 * Gets the neighbors state.
1630 *
1631 * @return neighbors state
1632 */
1633 public OspfNeighborState getState() {
1634 return state;
1635 }
1636
1637 /**
1638 * Sets the neighbors state.
1639 *
1640 * @param state neighbors state
1641 */
1642 public void setState(OspfNeighborState state) {
1643 this.state = state;
1644 }
1645
1646 /**
1647 * Sets neighbor is master or not.
1648 *
1649 * @param isMaster neighbor is master or not
1650 */
1651 public void setIsMaster(int isMaster) {
1652 this.isMaster = isMaster;
1653 }
1654
1655 /**
1656 * Gets the ls request list.
1657 *
1658 * @return ls request list
1659 */
1660 public Hashtable getLsReqList() {
1661 return lsReqList;
1662 }
1663
1664 /**
1665 * Gets the reTxList instance.
1666 *
1667 * @return reTxList instance
1668 */
1669 public Map getReTxList() {
1670 return reTxList;
1671 }
1672
1673 /**
1674 * Gets the pending re transmit list.
1675 *
1676 * @return pendingReTxList instance
1677 */
1678 public Map<String, OspfLsa> getPendingReTxList() {
1679 return pendingReTxList;
1680 }
1681
1682
1683 /**
1684 * Represents a Task which will do an inactivity time check.
1685 */
1686 private class InternalInactivityTimeCheck implements Runnable {
1687 /**
1688 * Constructor.
1689 */
1690 InternalInactivityTimeCheck() {
1691 }
1692
1693 @Override
1694 public void run() {
1695 try {
1696 log.debug("Neighbor Not Heard till the past router dead interval .");
1697 neighborDown();
1698 } catch (Exception e) {
1699 log.debug("Exception at inactivity time check...!!!");
1700 }
1701 }
1702 }
1703
1704 /**
1705 * Task which re transmits DdPacket every configured time interval.
1706 */
1707 private class InternalRxmtDdPacket implements Runnable {
1708 Channel ch;
1709
1710 /**
1711 * Creates an instance or Re transmit DD packet timer.
1712 *
1713 * @param ch netty channel instance
1714 */
1715 InternalRxmtDdPacket(Channel ch) {
1716 this.ch = ch;
1717 }
1718
1719 @Override
1720 public void run() {
1721 if ((ch != null) && ch.isConnected()) {
1722 DdPacket ddPacket = lastSentDdPacket();
1723 ch.write(ddPacket);
1724 log.debug("Re-Transmit DD Packet .");
1725 } else {
1726 log.debug(
1727 "Re-Transmit DD Packet failed. Channel not connected..");
1728 }
1729 }
1730 }
1731
1732 /**
1733 * Task which re transmits Ls request Packet every configured time interval.
1734 */
1735 private class InternalRxmtLsrPacket implements Runnable {
1736 Channel ch;
1737
1738 /**
1739 * Creates an instance or Re transmit LS Request packet timer.
1740 *
1741 * @param ch netty channel instance
1742 */
1743 InternalRxmtLsrPacket(Channel ch) {
1744 this.ch = ch;
1745 }
1746
1747 @Override
1748 public void run() {
1749 if ((ch != null) && ch.isConnected()) {
1750 LsRequest lsrPacket = getLastSentLsrPacket();
1751 ch.write(lsrPacket);
1752 log.debug("Re-Transmit LSRequest Packet .");
1753 } else {
1754 log.debug(
1755 "Re-Transmit LSRequest failed. Channel not connected..");
1756 }
1757 }
1758 }
1759
1760 /**
1761 * Task which transmits Ls update Packet based on the re transmit list.
1762 * every configured time interval.
1763 */
1764 private class InternalFloodingTask implements Runnable {
1765 Channel channel;
1766
1767 /**
1768 * Creates an instance or Flooding task.
1769 *
1770 * @param ch netty channel instance
1771 */
1772 InternalFloodingTask(Channel ch) {
1773 this.channel = ch;
1774 }
1775
1776 @Override
1777 public void run() {
1778 if ((channel != null) && channel.isConnected()) {
1779
1780 if ((pendingReTxList != null) && (pendingReTxList.size() > 0)) {
1781 List<LsUpdate> lsUpdateList = buildLsUpdate(pendingReTxList);
1782
1783 for (LsUpdate lsupdate : lsUpdateList) {
1784 //Pending for acknowledge directly sent it to neighbor
1785 lsupdate.setDestinationIp(neighborIpAddr);
1786 channel.write(lsupdate);
1787 }
1788 }
1789
1790 if ((reTxList != null) && (reTxList.size() > 0)) {
1791 List<LsUpdate> lsUpdateList = buildLsUpdate(reTxList);
1792
1793 for (LsUpdate lsupdate : lsUpdateList) {
1794 //set the destination
1795 if ((((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.DR) ||
1796 (((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.POINT2POINT)) {
1797 lsupdate.setDestinationIp(OspfUtil.ALL_SPF_ROUTERS);
1798 } else if (((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.DROTHER ||
1799 (((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.BDR)) {
1800 lsupdate.setDestinationIp(neighborDr);
1801 }
1802 channel.write(lsupdate);
1803 }
1804 }
1805 }
1806 }
1807
1808 /**
1809 * Builds the LsUpdate for flooding.
1810 *
1811 * @param txList list contains LSAs
1812 * @return list of LsUpdate instances
1813 */
1814 private List buildLsUpdate(Map<String, OspfLsa> txList) {
1815 List<LsUpdate> lsUpdateList = new ArrayList<>();
1816 ListIterator itr = new ArrayList(txList.keySet()).listIterator();
1817 while (itr.hasNext()) {
1818 LsUpdate lsupdate = new LsUpdate();
1819 // seting OSPF Header
1820 lsupdate.setOspfVer(OspfUtil.OSPF_VERSION);
1821 lsupdate.setOspftype(OspfPacketType.LSUPDATE.value());
1822 lsupdate.setRouterId(ospfArea.routerId());
1823 lsupdate.setAreaId(ospfArea.areaId());
1824 lsupdate.setAuthType(OspfUtil.NOT_ASSIGNED);
1825 lsupdate.setAuthentication(OspfUtil.NOT_ASSIGNED);
1826 lsupdate.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
1827 lsupdate.setChecksum(OspfUtil.NOT_ASSIGNED);
1828
1829 //limit to mtu
1830 int currentLength = OspfUtil.OSPF_HEADER_LENGTH + OspfUtil.FOUR_BYTES;
1831 int maxSize = ospfInterface.mtu() -
1832 OspfUtil.LSA_HEADER_LENGTH; // subtract a normal IP header.
1833
1834 int noLsa = 0;
1835 while (itr.hasNext()) {
1836
1837 String key = (String) itr.next();
1838 OspfLsa lsa = txList.get(key);
1839 if ((lsa.age() + OspfParameters.INFTRA_NS_DELAY) >= OspfParameters.MAXAGE) {
1840 ((LsaHeader) lsa.lsaHeader()).setAge(OspfParameters.MAXAGE);
1841 } else {
1842 ((LsaHeader) lsa.lsaHeader()).setAge(lsa.age() + OspfParameters.INFTRA_NS_DELAY);
1843 }
1844
1845 if ((currentLength + ((LsaHeader) lsa.lsaHeader()).lsPacketLen()) >= maxSize) {
1846 itr.previous();
1847 break;
1848 }
1849 log.debug("FloodingTimer::LSA Type::{}, Header: {}, LSA: {}", lsa.getOspfLsaType(),
1850 lsa.lsaHeader(), lsa);
1851
1852 if (lsa != null) {
1853 lsupdate.addLsa(lsa);
1854 noLsa++;
1855 currentLength = currentLength + ((LsaHeader) lsa.lsaHeader()).lsPacketLen();
1856 }
1857 log.debug("FloodingTimer::Removing key {}", key);
1858 if (txList.equals(reTxList)) {
1859 reTxList.remove(key);
1860 pendingReTxList.put(key, lsa);
1861 }
1862 }
1863 //set number of lsa's
1864 lsupdate.setNumberOfLsa(noLsa);
1865 lsUpdateList.add(lsupdate);
1866 }
1867 return lsUpdateList;
1868 }
1869 }
1870}