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