blob: f563a39232af3067057ef01238d546f309ea5572 [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
Ray Milkey0bb1e102016-11-10 14:51:27 -0800559 * @throws Exception on error
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530560 */
561 public void badLSReq(Channel ch) throws Exception {
562 log.debug("OSPFNbr::badLSReq...!!!");
563
564 if (state.getValue() >= OspfNeighborState.EXCHANGE.getValue()) {
565 if (state == OspfNeighborState.FULL) {
566 ospfArea.refreshArea(ospfInterface);
567 }
568
569 stopRxMtDdTimer();
570 state = OspfNeighborState.EXSTART;
571
572 lsReqList.clear();
573 ddSummaryList.clear();
574 reTxList.clear();
575 //increment the dd sequence number
576 isMaster = OspfUtil.IS_MASTER;
577 ddSeqNum++;
578 DdPacket ddPacket = new DdPacket();
579 // seting OSPF Header
580 ddPacket.setOspfVer(OspfUtil.OSPF_VERSION);
581 ddPacket.setOspftype(OspfPacketType.DD.value());
582 ddPacket.setRouterId(ospfArea.routerId());
583 ddPacket.setAreaId(ospfArea.areaId());
584 ddPacket.setAuthType(OspfUtil.NOT_ASSIGNED);
585 ddPacket.setAuthentication(OspfUtil.NOT_ASSIGNED);
586 ddPacket.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
587 ddPacket.setChecksum(OspfUtil.NOT_ASSIGNED);
588
589 // setting DD Body
590 boolean isOpaqueEnabled = ospfArea.isOpaqueEnabled();
591 if (isOpaqueEnabled && this.isOpaqueCapable) {
592 ddPacket.setOptions(ospfArea.opaqueEnabledOptions());
593 } else {
594 ddPacket.setOptions(ospfArea.options());
595 }
596 ddPacket.setIsInitialize(OspfUtil.INITIALIZE_SET);
597 ddPacket.setIsMore(OspfUtil.MORE_SET);
598 ddPacket.setIsMaster(OspfUtil.IS_MASTER);
599 ddPacket.setImtu(ospfInterface.mtu());
600 ddPacket.setSequenceNo(ddSeqNum);
601
602 rxmtDdPacketTask = new InternalRxmtDdPacket(ch);
603 startRxMtDdTimer(ch);
604
605 //setting destination ip
606 ddPacket.setDestinationIp(neighborIpAddr());
607 setLastSentDdPacket(ddPacket);
sunishvkf7c56552016-07-18 16:02:39 +0530608 byte[] messageToWrite = getMessage(ddPacket);
609 ch.write(messageToWrite);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530610 }
611 }
612
613 /**
614 * Called if state is EXCHANGE. This method is executed every time a DD Packets arrives.
615 * When the last Packet arrives, it transfers the state into LOADING or FULL
616 *
617 * @param neighborIsMaster true if neighbor is master else false
618 * @param dataDescPkt DdPacket instance
619 * @param ch netty channel instance
620 * @throws Exception might throws exception
621 */
622 public void processDdPacket(boolean neighborIsMaster, DdPacket dataDescPkt,
623 Channel ch) throws Exception {
624 log.debug("OSPFNbr::neighborIsMaster.{}", neighborIsMaster);
625
626 if (!neighborIsMaster) {
627 stopRxMtDdTimer();
628 ddSeqNum++;
629 processLsas(dataDescPkt.getLsaHeaderList());
630 if ((ddSummaryList.isEmpty()) &&
631 (dataDescPkt.isMore() == OspfUtil.MORE_NOTSET)) {
632 log.debug(
633 "OSPFNbr::ddSummaryList is empty and dataDescPkt.isMore is zero..!!!");
634 // generate the neighbor event ExchangeDone.
635 exchangeDone(dataDescPkt, ch);
636 } else {
637 log.debug("OSPFNbr::ddSummaryList is present...!!!");
638 // send a new Database Description Packet to the slave.
639 DdPacket ddPacket = new DdPacket();
640 // seting OSPF Header
641 ddPacket.setOspfVer(OspfUtil.OSPF_VERSION);
642 ddPacket.setOspftype(OspfPacketType.DD.value());
643 ddPacket.setRouterId(ospfArea.routerId());
644 ddPacket.setAreaId(ospfArea.areaId());
645 ddPacket.setAuthType(OspfUtil.NOT_ASSIGNED);
646 ddPacket.setAuthentication(OspfUtil.NOT_ASSIGNED);
647 ddPacket.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
648 ddPacket.setChecksum(OspfUtil.NOT_ASSIGNED);
649 // setting DD Body
650 boolean isOpaqueEnabled = ospfArea.isOpaqueEnabled();
651 if (isOpaqueEnabled && isOpaqueCapable) {
652 ddPacket.setOptions(ospfArea.opaqueEnabledOptions());
653 } else {
654 ddPacket.setOptions(ospfArea.options());
655 }
656 ddPacket.setIsInitialize(OspfUtil.INITIALIZE_NOTSET);
657 ddPacket.setIsMore(OspfUtil.MORE_NOTSET);
658 ddPacket.setIsMaster(OspfUtil.IS_MASTER);
659 ddPacket.setImtu(ospfInterface.mtu());
660 ddPacket.setSequenceNo(ddSeqNum);
661
662 setLastSentDdPacket(ddPacket);
663 getIsMoreBit();
664 //Set the destination IP Address
665 ddPacket.setDestinationIp(dataDescPkt.sourceIp());
sunishvkf7c56552016-07-18 16:02:39 +0530666 byte[] messageToWrite = getMessage(lastSentDdPacket());
667 ch.write(messageToWrite);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530668
669 startRxMtDdTimer(ch);
670 }
671 } else {
672 log.debug("OSPFNbr::neighborIsMaster is master...!!!");
673 ddSeqNum = dataDescPkt.sequenceNo();
674 processLsas(dataDescPkt.getLsaHeaderList());
675
676 DdPacket ddPacket = new DdPacket();
677 // seting OSPF Header
678 ddPacket.setOspfVer(OspfUtil.OSPF_VERSION);
679 ddPacket.setOspftype(OspfPacketType.DD.value());
680 ddPacket.setRouterId(ospfArea.routerId());
681 ddPacket.setAreaId(ospfArea.areaId());
682 ddPacket.setAuthType(OspfUtil.NOT_ASSIGNED);
683 ddPacket.setAuthentication(OspfUtil.NOT_ASSIGNED);
684 ddPacket.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
685 ddPacket.setChecksum(OspfUtil.NOT_ASSIGNED);
686 // setting DD Body
687 boolean isOpaqueEnabled = ospfArea.isOpaqueEnabled();
688 if (isOpaqueEnabled && this.isOpaqueCapable) {
689 ddPacket.setOptions(ospfArea.opaqueEnabledOptions());
690 } else {
691 ddPacket.setOptions(ospfArea.options());
692 }
693 ddPacket.setIsInitialize(OspfUtil.INITIALIZE_NOTSET);
694 ddPacket.setIsMore(OspfUtil.MORE_NOTSET);
695 ddPacket.setIsMaster(OspfUtil.NOT_MASTER);
696 ddPacket.setImtu(ospfInterface.mtu());
697 ddPacket.setSequenceNo(ddSeqNum);
698 setLastSentDdPacket(ddPacket);
699 getIsMoreBit();
700
701 if ((ddPacket.isMore() == OspfUtil.MORE_NOTSET) &&
702 (dataDescPkt.isMore() == OspfUtil.MORE_NOTSET)) {
703 // generate the neighbor event ExchangeDone.
704 exchangeDone(dataDescPkt, ch);
705 }
706
707 ddPacket.setDestinationIp(dataDescPkt.sourceIp());
sunishvkf7c56552016-07-18 16:02:39 +0530708 byte[] messageToWrite = getMessage(ddPacket);
709 ch.write(messageToWrite);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530710 }
711 }
712
713 /**
714 * Sets the more bit in stored, last sent DdPacket.
715 */
716 private void getIsMoreBit() {
717 DdPacket ddPacket = lastSentDdPacket();
718 int count = ddSummaryList.size();
719
720 if (!ddSummaryList.isEmpty()) {
721 Iterator itr = ddSummaryList.iterator();
722 int currentLength = OspfUtil.DD_HEADER_LENGTH;
723 int maxSize = ospfInterface.mtu() - OspfUtil.LSA_HEADER_LENGTH; // subtract a normal IP header.
724 while (itr.hasNext()) {
725 if ((currentLength + OspfUtil.LSA_HEADER_LENGTH) > maxSize) {
726 break;
727 }
728
729 LsaHeader lsaHeader = (LsaHeader) itr.next();
730 ddPacket.addLsaHeader(lsaHeader);
731 currentLength = currentLength + OspfUtil.LSA_HEADER_LENGTH;
732 ddSummaryList.remove(lsaHeader);
733 count--;
734 }
735
736 if (count > 0) {
737 ddPacket.setIsMore(OspfUtil.MORE_SET);
738 } else {
739 ddPacket.setIsMore(OspfUtil.MORE_NOTSET);
740 }
741 }
742
743 setLastSentDdPacket(ddPacket);
744 }
745
746 /**
747 * At this point, the router has sent and received an entire sequence of DD packets.
748 * Now it must be determined whether the new state is FULL, or LS Request packets
749 * have to be send.
750 *
751 * @param message OSPF message instance
752 * @param ch netty channel handler
753 */
754 public void exchangeDone(OspfMessage message, Channel ch) {
755 log.debug("OSPFNbr::exchangeDone...!!!");
756 stopRxMtDdTimer();
757
758 OspfPacketHeader header = (OspfPacketHeader) message;
759
760 if (state == OspfNeighborState.EXCHANGE) {
761 if (lsReqList.isEmpty()) {
762 state = OspfNeighborState.FULL;
763 //handler.addDeviceInformation(this);
764 //handler.addLinkInformation(this, topLevelTlvs);
765 } else {
766 state = OspfNeighborState.LOADING;
767 LsRequest lsRequest = buildLsRequest();
768 //Setting the destination address
769 lsRequest.setDestinationIp(header.sourceIp());
sunishvkf7c56552016-07-18 16:02:39 +0530770 byte[] messageToWrite = getMessage(lsRequest);
771 ch.write(messageToWrite);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530772
773 setLastSentLsrPacket(lsRequest);
774 startRxMtLsrTimer(ch);
775 }
776 }
777 }
778
779 /**
780 * Builds LS Request.
781 *
782 * @return ls request instance
783 */
784 private LsRequest buildLsRequest() {
785 //send link state request packet to neighbor
786 //for recent lsa's which are not received in exchange state
787 LsRequest lsRequest = new LsRequest();
788 lsRequest.setOspfVer(OspfUtil.OSPF_VERSION);
789 lsRequest.setOspftype(OspfPacketType.LSREQUEST.value());
790 lsRequest.setRouterId(ospfArea.routerId());
791 lsRequest.setAreaId(ospfArea.areaId());
792 lsRequest.setAuthType(OspfUtil.NOT_ASSIGNED);
793 lsRequest.setAuthentication(OspfUtil.NOT_ASSIGNED);
794 lsRequest.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
795 lsRequest.setChecksum(OspfUtil.NOT_ASSIGNED);
796
797 Set lsaKeys = lsReqList.keySet();
798 Iterator itr = lsaKeys.iterator();
799
800 int currentLength = OspfUtil.OSPF_HEADER_LENGTH;
801 int maxSize = ospfInterface.mtu() -
802 OspfUtil.LSA_HEADER_LENGTH; // subtract a normal IP header.
803
804 while (itr.hasNext()) {
805 if ((currentLength + OspfUtil.LSREQUEST_LENGTH) >= maxSize) {
806 break;
807 }
808 LsRequestPacket lsRequestPacket = new LsRequestPacket();
809
810 String key = ((String) itr.next());
811 String[] lsaKey = key.split("-");
812 OspfLsa lsa = (OspfLsa) lsReqList.get(key);
813
814 lsRequestPacket.setLsType(Integer.valueOf(lsaKey[0]));
815 lsRequestPacket.setOwnRouterId(lsaKey[2]);
816
817 if (((lsa.getOspfLsaType().value() == OspfLsaType.AREA_LOCAL_OPAQUE_LSA.value()) ||
818 (lsa.getOspfLsaType().value() == OspfLsaType.LINK_LOCAL_OPAQUE_LSA.value())) ||
819 (lsa.getOspfLsaType().value() == OspfLsaType.AS_OPAQUE_LSA.value())) {
820 OpaqueLsaHeader header = (OpaqueLsaHeader) lsa;
821 byte[] opaqueIdBytes = OspfUtil.convertToTwoBytes(header.opaqueId());
822 lsRequestPacket.setLinkStateId(header.opaqueType() + "." + "0" + "." + opaqueIdBytes[0]
823 + "." + opaqueIdBytes[1]);
824 } else {
825 lsRequestPacket.setLinkStateId(lsaKey[1]);
826 }
827
828 lsRequest.addLinkStateRequests(lsRequestPacket);
829 currentLength = currentLength + OspfUtil.LSREQUEST_LENGTH;
830 }
831
832 return lsRequest;
833 }
834
835 /**
836 * Determines whether an adjacency should be established/maintained with the neighbor or not.
837 *
838 * @param ch netty channel instance
839 */
840 public void adjOk(Channel ch) {
841 log.debug("OSPFNbr::adjOk...!!!");
842 if (ospfInterface.interfaceType() != OspfInterfaceType.POINT_TO_POINT.value()) {
843 if (state == OspfNeighborState.TWOWAY) {
844 if (formAdjacencyOrNot()) {
845 state = OspfNeighborState.EXSTART;
846 //check for sequence number in lsdb
847 ddSeqNum++;
848
849 DdPacket ddPacket = new DdPacket();
850 // seting OSPF Header
851 ddPacket.setOspfVer(OspfUtil.OSPF_VERSION);
852 ddPacket.setOspftype(OspfPacketType.DD.value());
853 ddPacket.setRouterId(ospfArea.routerId());
854 ddPacket.setAreaId(ospfArea.areaId());
855 ddPacket.setAuthType(OspfUtil.NOT_ASSIGNED);
856 ddPacket.setAuthentication(OspfUtil.NOT_ASSIGNED);
857 ddPacket.setOspfPacLength(OspfUtil.NOT_ASSIGNED);
858 ddPacket.setChecksum(OspfUtil.NOT_ASSIGNED);
859
860 // setting DD Body
861 boolean isOpaqueEnabled = ospfArea.isOpaqueEnabled();
862 if (isOpaqueEnabled && this.isOpaqueCapable) {
863 ddPacket.setOptions(ospfArea.opaqueEnabledOptions());
864 } else {
865 ddPacket.setOptions(ospfArea.options());
866 }
867 ddPacket.setIsInitialize(OspfUtil.INITIALIZE_SET);
868 ddPacket.setIsMore(OspfUtil.MORE_SET);
869 ddPacket.setIsMaster(OspfUtil.IS_MASTER);
870 ddPacket.setImtu(ospfInterface.mtu());
871 ddPacket.setSequenceNo(ddSeqNum);
872 rxmtDdPacketTask = new InternalRxmtDdPacket(ch);
873 startRxMtDdTimer(ch);
874 //setting destination ip
875 ddPacket.setDestinationIp(neighborIpAddr());
876 setLastSentDdPacket(ddPacket);
sunishvkf7c56552016-07-18 16:02:39 +0530877 byte[] messageToWrite = getMessage(ddPacket);
878 ch.write(messageToWrite);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530879 }
880 } else if (state.getValue() >= OspfNeighborState.EXSTART.getValue()) {
881 if (!formAdjacencyOrNot()) {
882 state = OspfNeighborState.TWOWAY;
883 lsReqList.clear();
884 ddSummaryList.clear();
885 reTxList.clear();
886 }
887 }
888 }
889 }
890
891 /**
892 * LS Update Packet has been received while state was EXCHANGE or LOADING.
893 * Examine the received LSAs, check whether they were requested or not and process
894 * them accordingly. Therefore use method "processReceivedLsa" for further treatment.
895 *
896 * @param lsUpdPkt LS Update Packet received while Neighbor state was EXCHANGE or
897 * LOADING
898 * @param ch netty channel instance
899 * @throws Exception might throws exception
900 */
901 public void processLsUpdate(LsUpdate lsUpdPkt, Channel ch) throws Exception {
902 stopRxMtLsrTimer();
903 log.debug("OSPFNbr::processLsUpdate...!!!");
904
905 List lsaList = lsUpdPkt.getLsaList();
906 if (!lsaList.isEmpty()) {
907 Iterator itr = lsaList.iterator();
908
909 while (itr.hasNext()) {
910 LsaHeader lsaHeader = (LsaHeader) itr.next();
911 String key = ((OspfAreaImpl) ospfArea).getLsaKey(lsaHeader);
912
913 if (lsReqList.containsKey(key)) {
914 boolean removeIt;
915 removeIt = processReceivedLsa(lsaHeader, false, ch,
916 lsUpdPkt.sourceIp());
917 if (removeIt) {
918 lsReqList.remove(key);
919 }
920 } else {
921 // LSA was received via Flooding
922 processReceivedLsa(lsaHeader, true, ch,
923 lsUpdPkt.sourceIp());
924 }
925 }
926
927 if (lsReqList.isEmpty() && (state == OspfNeighborState.LOADING)) {
928 // loading complete
929 loadingDone();
930 } else {
931 stopRxMtLsrTimer();
932 LsRequest lsRequest = buildLsRequest();
933 lsRequest.setDestinationIp(lsUpdPkt.sourceIp());
934 setLastSentLsrPacket(lsRequest);
935
936 startRxMtLsrTimer(ch);
937 }
938 }
939 }
940
941 /***
942 * Method gets called when no more ls request list and moving to FULL State.
943 *
944 * @throws Exception might throws exception
945 */
946 public void loadingDone() throws Exception {
947 stopRxMtLsrTimer();
948 stopRxMtDdTimer();
949 log.debug("OSPFNbr::loadingDone...!!!");
950 state = OspfNeighborState.FULL;
951 ospfArea.refreshArea(ospfInterface);
952 }
953
954 /**
955 * Adds device and link.
956 *
957 * @param topologyForDeviceAndLink topology for device and link instance
958 */
959 private void callDeviceAndLinkAdding(TopologyForDeviceAndLink topologyForDeviceAndLink) {
960 Map<String, DeviceInformation> deviceInformationMap = topologyForDeviceAndLink.deviceInformationMap();
sunishvkf7c56552016-07-18 16:02:39 +0530961 Map<String, DeviceInformation> deviceInformationMapForPointToPoint =
962 topologyForDeviceAndLink.deviceInformationMapForPointToPoint();
963 Map<String, DeviceInformation> deviceInformationMapToDelete =
964 topologyForDeviceAndLink.deviceInformationMapToDelete();
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530965 Map<String, LinkInformation> linkInformationMap = topologyForDeviceAndLink.linkInformationMap();
sunishvkf7c56552016-07-18 16:02:39 +0530966 Map<String, LinkInformation> linkInformationMapForPointToPoint =
967 topologyForDeviceAndLink.linkInformationMapForPointToPoint();
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530968 OspfRouter ospfRouter = new OspfRouterImpl();
sunishvkf7c56552016-07-18 16:02:39 +0530969
970 if (deviceInformationMap.size() != 0) {
971 for (String key : deviceInformationMap.keySet()) {
972 DeviceInformation value = deviceInformationMap.get(key);
973 ospfRouter.setRouterIp(value.routerId());
974 ospfRouter.setAreaIdOfInterface(ospfArea.areaId());
975 ospfRouter.setNeighborRouterId(value.deviceId());
976 OspfDeviceTed ospfDeviceTed = new OspfDeviceTedImpl();
977 List<Ip4Address> ip4Addresses = value.interfaceId();
978 ospfDeviceTed.setIpv4RouterIds(ip4Addresses);
979 ospfRouter.setDeviceTed(ospfDeviceTed);
980 ospfRouter.setOpaque(ospfArea.isOpaqueEnabled());
981 if (value.isDr()) {
982 ospfRouter.setDr(value.isDr());
983 } else {
984 ospfRouter.setDr(false);
985 }
986 int size = value.interfaceId().size();
987 for (int i = 0; i < size; i++) {
988 ospfRouter.setInterfaceId(value.interfaceId().get(i));
989 }
990 ((OspfInterfaceImpl) ospfInterface).addDeviceInformation(ospfRouter);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530991 }
sunishvkf7c56552016-07-18 16:02:39 +0530992 }
993 if (deviceInformationMapForPointToPoint.size() != 0) {
994 for (String key : deviceInformationMapForPointToPoint.keySet()) {
995 DeviceInformation value = deviceInformationMapForPointToPoint.get(key);
996 ospfRouter.setRouterIp(value.routerId());
997 ospfRouter.setAreaIdOfInterface(ospfArea.areaId());
998 ospfRouter.setNeighborRouterId(value.deviceId());
999 OspfDeviceTed ospfDeviceTed = new OspfDeviceTedImpl();
1000 List<Ip4Address> ip4Addresses = value.interfaceId();
1001 ospfDeviceTed.setIpv4RouterIds(ip4Addresses);
1002 ospfRouter.setDeviceTed(ospfDeviceTed);
1003 ospfRouter.setOpaque(value.isDr());
1004 int size = value.interfaceId().size();
1005 for (int i = 0; i < size; i++) {
1006 ospfRouter.setInterfaceId(value.interfaceId().get(i));
1007 }
1008 ((OspfInterfaceImpl) ospfInterface).addDeviceInformation(ospfRouter);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301009 }
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301010 }
1011 for (Map.Entry<String, LinkInformation> entry : linkInformationMap.entrySet()) {
1012 String key = entry.getKey();
1013 LinkInformation value = entry.getValue();
1014 OspfRouter ospfRouterForLink = new OspfRouterImpl();
1015 ospfRouterForLink.setInterfaceId(value.interfaceIp());
1016 ospfRouterForLink.setAreaIdOfInterface(ospfArea.areaId());
1017 ospfRouterForLink.setOpaque(ospfArea.isOpaqueEnabled());
sunishvkf7c56552016-07-18 16:02:39 +05301018 OspfLinkTed ospfLinkTed = topologyForDeviceAndLink.getOspfLinkTedHashMap(
1019 value.linkDestinationId().toString());
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301020 if (ospfLinkTed == null) {
1021 ospfLinkTed = new OspfLinkTedImpl();
1022 ospfLinkTed.setMaximumLink(Bandwidth.bps(0));
1023 ospfLinkTed.setMaxReserved(Bandwidth.bps(0));
1024 ospfLinkTed.setTeMetric(0);
1025 }
1026
1027 if (!value.isLinkSrcIdNotRouterId()) {
1028 ospfRouterForLink.setRouterIp(value.linkSourceId());
1029 ospfRouterForLink.setNeighborRouterId(value.linkDestinationId());
1030 try {
sunishvkf7c56552016-07-18 16:02:39 +05301031 ((OspfInterfaceImpl) ospfInterface).addLinkInformation(ospfRouterForLink, ospfLinkTed);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301032 } catch (Exception e) {
sunishvkf7c56552016-07-18 16:02:39 +05301033 log.debug("Exception addLinkInformation: " + e.getMessage());
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301034 }
1035 }
1036 }
1037 }
1038
1039 // RFC 2328 Section 13 - partly as flooding procedure
1040
1041 /**
1042 * Processes the received Lsa.
1043 *
1044 * @param recLsa received Lsa
1045 * @param receivedViaFlooding received via flooding or not
1046 * @param ch channel instance
1047 * @param sourceIp source of this Lsa
1048 * @return true to remove it from lsReqList else false
1049 * @throws Exception might throws exception
1050 */
1051 public boolean processReceivedLsa(LsaHeader recLsa,
1052 boolean receivedViaFlooding, Channel ch, Ip4Address sourceIp)
1053 throws Exception {
1054 log.debug("OSPFNbr::processReceivedLsa(recLsa, recievedViaFlooding, ch)...!!!");
1055
1056 //Validate the lsa checksum RFC 2328 13 (1)
1057 ChecksumCalculator checkSum = new ChecksumCalculator();
1058 if (!checkSum.isValidLsaCheckSum(recLsa,
1059 recLsa.getOspfLsaType().value(),
1060 OspfUtil.LSAPACKET_CHECKSUM_POS1,
1061 OspfUtil.LSAPACKET_CHECKSUM_POS2)) {
1062 log.debug("Checksum mismatch. Received LSA packet type {} ",
1063 recLsa.lsType());
1064
1065 return true;
1066 }
1067
1068 //If LSA type is unknown discard the lsa RFC 2328 13(2)
1069 if (((recLsa.getOspfLsaType().value() > OspfLsaType.EXTERNAL_LSA.value()) &&
1070 (recLsa.getOspfLsaType().value() < OspfLsaType.LINK_LOCAL_OPAQUE_LSA.value())) ||
1071 (recLsa.getOspfLsaType().value() > OspfLsaType.AS_OPAQUE_LSA.value())) {
1072 return true;
1073 }
1074
1075 //If LSA type is external & the area is configured as stub area discard the lsa RFC 2328 13(3)
1076 if ((recLsa.getOspfLsaType() == OspfLsaType.EXTERNAL_LSA) &&
sunish vkaa48da82016-03-02 23:17:06 +05301077 (!ospfArea.isExternalRoutingCapability())) {
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301078 return true;
1079 }
1080
1081 //if lsa age is equal to maxage && instance is not in lsdb && none of neighbors are in exchange
1082 // or loading state
1083 // Acknowledge the receipt by sending LSAck to the sender. 2328 13(4)
1084 if ((recLsa.age() == OspfParameters.MAXAGE) &&
1085 (ospfArea.lsaLookup(recLsa) == null) &&
1086 ospfArea.noNeighborInLsaExchangeProcess()) {
1087 // RFC 2328 Section 13. (4)
1088 // Because the LSA was not yet requested, it is treated as a flooded LSA and thus
1089 // acknowledged.
1090 directAcknowledge(recLsa, ch, sourceIp);
1091 return true;
1092 }
1093
1094 String key = ((OspfAreaImpl) ospfArea).getLsaKey(recLsa);
1095 LsaWrapper lsWrapper = ospfArea.lsaLookup(recLsa);
1096 String status = isNullorLatest(lsWrapper, recLsa);
1097 //Section 13 (5)
1098 if (status.equals("isNullorLatest")) {
1099
1100 if (recLsa.lsType() == OspfLsaType.ROUTER.value() && recLsa.advertisingRouter().equals(
1101 ospfArea.routerId())) {
1102 if (recLsa.lsSequenceNo() > ((LsaWrapperImpl) lsWrapper).lsaHeader().lsSequenceNo()) {
1103 ospfArea.setDbRouterSequenceNumber(recLsa.lsSequenceNo() + 1);
1104 processSelfOriginatedLsa();
1105 }
1106
1107 if (recLsa.age() == OspfParameters.MAXAGE) {
1108 ((LsaWrapperImpl) lsWrapper).lsaHeader().setAge(OspfParameters.MAXAGE);
1109 //remove from db & bin, add the lsa to MaxAge bin.
1110 ospfArea.addLsaToMaxAgeBin(((OspfAreaImpl) ospfArea).getLsaKey(((LsaWrapperImpl)
1111 lsWrapper).lsaHeader()), lsWrapper);
1112 ospfArea.removeLsaFromBin(lsWrapper);
1113 }
1114
1115 return true;
1116 } else if (recLsa.lsType() == OspfLsaType.NETWORK.value() && isLinkStateMatchesOwnRouterId(
1117 recLsa.linkStateId())) {
1118 // if we are not DR or if origination router ID not equal to our router ID //either
1119 // DR state changed or our router ID was changed
1120 //set LSAge = MaxAge
1121 //flood the LSA
1122 if (((OspfInterfaceImpl) ospfInterface).state() != OspfInterfaceState.DR ||
1123 !recLsa.advertisingRouter().equals(
1124 ospfArea.routerId())) {
1125 if (lsWrapper != null) {
1126 ((LsaWrapperImpl) lsWrapper).lsaHeader().setAge(OspfParameters.MAXAGE);
1127 //remove from bin, add the lsa to MaxAge bin.
1128 ospfArea.addLsaToMaxAgeBin(((OspfAreaImpl) ospfArea).getLsaKey(((LsaWrapperImpl)
1129 lsWrapper).lsaHeader()), lsWrapper);
1130 ospfArea.removeLsaFromBin(lsWrapper);
1131 } else {
1132 recLsa.setAge(OspfParameters.MAXAGE);
1133 ((OspfAreaImpl) ospfArea).addToOtherNeighborLsaTxList(recLsa);
1134 }
1135 }
1136
1137 return true;
1138 } else {
1139 if (recLsa.age() == OspfParameters.MAXAGE) {
1140 ((OspfInterfaceImpl) ospfInterface).addLsaHeaderForDelayAck(recLsa);
1141 //remove from db & bin, add the lsa to MaxAge bin.
1142 if (lsWrapper != null) {
1143 lsWrapper.setLsaAgeReceived(OspfParameters.MAXAGE);
1144 ospfArea.addLsaToMaxAgeBin(((OspfAreaImpl) ospfArea).getLsaKey(((LsaWrapperImpl)
1145 lsWrapper).lsaHeader()), lsWrapper);
1146 ospfArea.removeLsaFromBin(lsWrapper);
1147 } else {
1148 ((OspfAreaImpl) ospfArea).addToOtherNeighborLsaTxList(recLsa);
1149 }
1150
1151 return true;
1152 } else {
1153 ospfArea.addLsa(recLsa, ospfInterface);
1154 log.debug("Inside addLsaMethod");
1155 topologyForDeviceAndLink.addLocalDevice(recLsa, ospfInterface, ospfArea);
1156 callDeviceAndLinkAdding(topologyForDeviceAndLink);
1157 log.debug("Adding to lsdb interface State {}", ((OspfInterfaceImpl) ospfInterface).state().value());
1158 // should not send any acknowledge if flooded out on receiving interface
1159 if (((OspfInterfaceImpl) ospfInterface).state().value() == OspfInterfaceState.BDR.value()) {
1160 if (neighborDr.equals(sourceIp)) {
1161 log.debug("Adding for delayed ack {}", recLsa);
1162 ((OspfInterfaceImpl) ospfInterface).addLsaHeaderForDelayAck(recLsa);
1163 }
1164 } else {
1165 log.debug("Adding for delayed ack {}", recLsa);
1166 ((OspfInterfaceImpl) ospfInterface).addLsaHeaderForDelayAck(recLsa);
1167 }
1168
1169 if (((OspfInterfaceImpl) ospfInterface).state().value() == OspfInterfaceState.DR.value() ||
1170 ((OspfInterfaceImpl) ospfInterface).state().value() ==
1171 OspfInterfaceState.POINT2POINT.value()) {
1172 ((OspfAreaImpl) ospfArea).addToOtherNeighborLsaTxList(recLsa);
1173 }
1174 }
1175
1176 }
1177 }
1178 // RFC 2328 Section 13 (6)
1179 if (lsReqList.contains(key)) {
1180 badLSReq(ch);
1181 }
1182 if (status.equals("same")) { //13 (7)
1183 if (pendingReTxList.containsKey(key)) {
1184 pendingReTxList.remove(key);
1185 if (((OspfInterfaceImpl) ospfInterface).state().value() == OspfInterfaceState.BDR.value()) {
1186 if (neighborDr.equals(recLsa.advertisingRouter())) {
1187 ((OspfInterfaceImpl) ospfInterface).addLsaHeaderForDelayAck(recLsa);
1188 }
1189 }
1190 } else {
1191 directAcknowledge(recLsa, ch, sourceIp);
1192 return true;
1193 }
1194 } else if (status.equals("old")) { // section 13 - point 8
1195 if ((recLsa.lsSequenceNo() == OspfParameters.MAXSEQUENCENUMBER) &&
1196 (recLsa.age() == OspfParameters.MAXAGE)) {
1197 // section 13 - point 8
1198 // simple discard the received LSA -
1199 return true;
1200 } else {
1201 // respond back with the same LSA
1202 //Using flood LSA to sent the LSUpdate back to advertising router
1203 int diff = Math.abs(lsWrapper.lsaAgeReceived() - recLsa.age());
1204 if (diff > OspfParameters.MINLSARRIVAL) {
1205 sendLsa(((LsaWrapperImpl) lsWrapper).lsaHeader(), sourceIp, ch);
1206 }
1207 }
1208 }
sunishvkf7c56552016-07-18 16:02:39 +05301209
1210 constructDeviceInformationFromDb();
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301211 callDeviceAndLinkAdding(topologyForDeviceAndLink);
sunishvkf7c56552016-07-18 16:02:39 +05301212
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301213 return true;
1214 }
1215
1216 /**
sunishvkf7c56552016-07-18 16:02:39 +05301217 * Constructs device and link information from link state database.
1218 */
1219 private void constructDeviceInformationFromDb() {
1220 OspfLsdb database = ospfArea.database();
1221 List lsas = database.getAllLsaHeaders(true, true);
1222 Iterator iterator = lsas.iterator();
1223 while (iterator.hasNext()) {
1224 OspfLsa ospfLsa = (OspfLsa) iterator.next();
1225 if (ospfLsa.getOspfLsaType().value() == OspfLsaType.ROUTER.value()) {
1226 topologyForDeviceAndLink.addLocalDevice(ospfLsa, ospfInterface, ospfArea);
1227 } else if (ospfLsa.getOspfLsaType().value() == OspfLsaType.NETWORK.value()) {
1228 topologyForDeviceAndLink.addLocalDevice(ospfLsa, ospfInterface, ospfArea);
1229 }
1230 }
1231 }
1232
1233 /**
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301234 * Checks Link State ID is equal to one of the router's own IP interface addresses.
1235 *
1236 * @param linkStateId link state id
1237 * @return true if link state matches or false
1238 */
1239 private boolean isLinkStateMatchesOwnRouterId(String linkStateId) {
1240 boolean isLinkStateMatches = false;
sunishvkf7c56552016-07-18 16:02:39 +05301241 List<OspfInterface> interfaceLst = ospfArea.ospfInterfaceList();
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301242 for (OspfInterface ospfInterface : interfaceLst) {
1243 if (ospfInterface.ipAddress().toString().equals(linkStateId)) {
1244 isLinkStateMatches = true;
1245 break;
1246 }
1247 }
1248
1249 return isLinkStateMatches;
1250 }
1251
1252 /**
1253 * RFC 2328 Section 13 (5).
1254 *
1255 * @param lsWrapper ls wrapper instance
1256 * @param recLsa received LSA instance
1257 * @return returns a string status
1258 */
1259 public String isNullorLatest(LsaWrapper lsWrapper, LsaHeader recLsa) {
1260
1261
1262 if (lsWrapper != null) {
1263 LsaHeader ownLsa = (LsaHeader) lsWrapper.ospfLsa();
1264 String status = ospfArea.isNewerOrSameLsa(recLsa, ownLsa);
1265
1266 if (status.equals("latest")) {
1267 return "isNullorLatest";
1268 } else {
1269 return status;
1270 }
1271 } else {
1272 return "isNullorLatest";
1273 }
1274 }
1275
1276 /**
1277 * RFC 2328 section 13.4
1278 * Processing self-originated LSAs.
1279 *
1280 * @throws Exception might throws exception
1281 */
1282 public void processSelfOriginatedLsa() throws Exception {
1283 ospfArea.refreshArea(ospfInterface);
1284 }
1285
1286 /**
1287 * Sends the LSA to destination address.
1288 *
1289 * @param lsa LSA instance to sent
1290 * @param destination destination IP address
1291 * @param ch netty channel instance
1292 */
1293 public void sendLsa(LsaHeader lsa, Ip4Address destination, Channel ch) {
1294 if (lsa == null) {
1295 return;
1296 }
1297
1298 LsUpdate responseLsUpdate = new LsUpdate();
1299 // seting OSPF Header
1300 responseLsUpdate.setOspfVer(OspfUtil.OSPF_VERSION);
1301 responseLsUpdate.setOspftype(OspfPacketType.LSUPDATE.value());
1302 responseLsUpdate.setRouterId(ospfArea.routerId());
1303 responseLsUpdate.setAreaId(ospfArea.areaId());
1304 responseLsUpdate.setAuthType(OspfUtil.NOT_ASSIGNED);
1305 responseLsUpdate.setAuthentication(OspfUtil.NOT_ASSIGNED);
1306 responseLsUpdate.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
1307 responseLsUpdate.setChecksum(OspfUtil.NOT_ASSIGNED);
1308 responseLsUpdate.setNumberOfLsa(1);
1309 responseLsUpdate.addLsa(lsa);
1310
1311 //setting the destination.
1312 responseLsUpdate.setDestinationIp(destination);
sunishvkf7c56552016-07-18 16:02:39 +05301313 byte[] messageToWrite = getMessage(responseLsUpdate);
1314 ch.write(messageToWrite);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301315 }
1316
1317 /**
1318 * Sends a direct Acknowledgment for a particular LSA to the Neighbor.
1319 *
1320 * @param ackLsa LSA instance
1321 * @param ch netty channel instance
1322 * @param sourceIp source IP address
1323 */
1324 public void directAcknowledge(LsaHeader ackLsa, Channel ch, Ip4Address sourceIp) {
1325 log.debug("OSPFNbr::directAcknowledge...!!!");
1326
1327 LsAcknowledge ackContent = new LsAcknowledge();
1328 // seting OSPF Header
1329 ackContent.setOspfVer(OspfUtil.OSPF_VERSION);
1330 ackContent.setOspftype(OspfPacketType.LSAACK.value());
1331 ackContent.setRouterId(ospfArea.routerId());
1332 ackContent.setAreaId(ospfArea.areaId());
1333 ackContent.setAuthType(OspfUtil.NOT_ASSIGNED);
1334 ackContent.setAuthentication(OspfUtil.NOT_ASSIGNED);
1335 ackContent.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
1336 ackContent.setChecksum(OspfUtil.NOT_ASSIGNED);
1337 ackContent.addLinkStateHeader(ackLsa);
1338 //setting the destination IP
1339 ackContent.setDestinationIp(sourceIp);
sunishvkf7c56552016-07-18 16:02:39 +05301340 byte[] messageToWrite = getMessage(ackContent);
1341 ch.write(messageToWrite);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301342 }
1343
1344 /**
1345 * Called when neighbor is down.
1346 *
1347 * @throws Exception might throws exception
1348 */
1349 public void neighborDown() throws Exception {
1350 log.debug("Neighbor Down {} and NeighborId {}", neighborIpAddr,
1351 neighborId);
1352 stopInactivityTimeCheck();
1353 stopRxMtDdTimer();
1354 stopRxMtLsrTimer();
1355
1356 if (floodingTimerScheduled) {
1357 stopFloodingTimer();
1358 floodingTimerScheduled = false;
1359 }
1360
1361 state = OspfNeighborState.DOWN;
1362 ospfArea.refreshArea(ospfInterface);
1363 lsReqList.clear();
1364 ddSummaryList.clear();
1365 if (neighborIpAddr.equals(neighborBdr) ||
1366 neighborIpAddr.equals(neighborDr)) {
sunishvkf7c56552016-07-18 16:02:39 +05301367 ((OspfInterfaceImpl) ospfInterface).neighborChange();
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301368 }
1369 log.debug("Neighbor Went Down : "
1370 + this.neighborIpAddr + " , " + this.neighborId);
1371 removeDeviceDetails(this.neighborId);
1372 OspfRouter ospfRouter = new OspfRouterImpl();
1373 ospfRouter.setRouterIp(this.neighborId());
1374 ospfRouter.setInterfaceId(ospfInterface.ipAddress());
1375 ospfRouter.setAreaIdOfInterface(ospfArea.areaId());
1376 ospfRouter.setDeviceTed(new OspfDeviceTedImpl());
sunishvkf7c56552016-07-18 16:02:39 +05301377 ((OspfInterfaceImpl) ospfInterface).removeDeviceInformation(ospfRouter);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301378 removeDeviceDetails(this.neighborIpAddr);
1379 OspfRouter ospfRouter1 = new OspfRouterImpl();
1380 ospfRouter1.setRouterIp(this.neighborIpAddr);
1381 ospfRouter1.setInterfaceId(ospfInterface.ipAddress());
1382 ospfRouter1.setAreaIdOfInterface(ospfArea.areaId());
1383 ospfRouter1.setDeviceTed(new OspfDeviceTedImpl());
sunishvkf7c56552016-07-18 16:02:39 +05301384 ((OspfInterfaceImpl) ospfInterface).removeDeviceInformation(ospfRouter1);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301385 }
1386
1387 /**
1388 * Removes device details.
1389 *
1390 * @param routerId router id
1391 */
1392 private void removeDeviceDetails(Ip4Address routerId) {
1393 String key = "device:" + routerId;
1394 topologyForDeviceAndLink.removeDeviceInformationMap(key);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301395 }
1396
1397 /**
1398 * Starts the inactivity timer.
1399 */
sunishvkf7c56552016-07-18 16:02:39 +05301400 public void startInactivityTimeCheck() {
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301401 if (!inActivityTimerScheduled) {
1402 log.debug("OSPFNbr::startInactivityTimeCheck");
1403 inActivityTimeCheckTask = new InternalInactivityTimeCheck();
1404 exServiceInActivity = Executors.newSingleThreadScheduledExecutor();
1405 exServiceInActivity.scheduleAtFixedRate(inActivityTimeCheckTask, routerDeadInterval,
1406 routerDeadInterval, TimeUnit.SECONDS);
1407 inActivityTimerScheduled = true;
1408 }
1409 }
1410
1411 /**
1412 * Stops the inactivity timer.
1413 */
sunishvkf7c56552016-07-18 16:02:39 +05301414 public void stopInactivityTimeCheck() {
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301415 if (inActivityTimerScheduled) {
1416 log.debug("OSPFNbr::stopInactivityTimeCheck ");
1417 exServiceInActivity.shutdown();
1418 inActivityTimerScheduled = false;
1419 }
1420 }
1421
1422 /**
1423 * Starts the flooding timer.
1424 *
1425 * @param channel channel instance
1426 */
1427 public void startFloodingTimer(Channel channel) {
1428
1429 if (!floodingTimerScheduled) {
1430 log.debug("OSPFNbr::startFloodingTimer");
1431 floodingTask = new InternalFloodingTask(channel);
1432 exServiceFlooding = Executors.newSingleThreadScheduledExecutor();
1433 //Run every 5 seconds.
1434 exServiceFlooding.scheduleAtFixedRate(floodingTask, OspfParameters.START_NOW,
1435 OspfParameters.MINLSINTERVAL, TimeUnit.SECONDS);
1436 floodingTimerScheduled = true;
1437 }
1438 }
1439
1440 /**
1441 * Stops the flooding timer.
1442 */
sunishvkf7c56552016-07-18 16:02:39 +05301443 public void stopFloodingTimer() {
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301444 if (floodingTimerScheduled) {
1445 log.debug("OSPFNbr::stopFloodingTimer ");
1446 exServiceFlooding.shutdown();
1447 floodingTimerScheduled = false;
1448 }
1449 }
1450
1451 /**
1452 * Starts the Dd Retransmission executor task.
1453 *
1454 * @param ch netty channel instance
1455 */
1456 private void startRxMtDdTimer(Channel ch) {
1457 if (!rxmtDdPacketTimerScheduled) {
1458 long retransmitInterval = ospfInterface.reTransmitInterval();
1459 rxmtDdPacketTask = new InternalRxmtDdPacket(ch);
1460 exServiceRxmtDDPacket = Executors.newSingleThreadScheduledExecutor();
1461 exServiceRxmtDDPacket.scheduleAtFixedRate(rxmtDdPacketTask, retransmitInterval,
1462 retransmitInterval, TimeUnit.SECONDS);
1463 rxmtDdPacketTimerScheduled = true;
1464 }
1465 }
1466
1467 /**
1468 * Stops the Dd Retransmission executor task.
1469 */
sunishvkf7c56552016-07-18 16:02:39 +05301470 public void stopRxMtDdTimer() {
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301471 if (rxmtDdPacketTimerScheduled) {
1472 exServiceRxmtDDPacket.shutdown();
1473 rxmtDdPacketTimerScheduled = false;
1474 }
1475 }
1476
1477 /**
1478 * Starts Ls request retransmission executor task.
1479 *
1480 * @param ch Netty channel instance
1481 */
1482 private void startRxMtLsrTimer(Channel ch) {
1483 if (!rxmtLsrTimerScheduled) {
1484 log.debug("OSPFNbr::startRxMtLsrTimer...!!!");
1485 long retransmitIntrvl = ospfInterface.reTransmitInterval();
1486 rxmtLsrPacketTask = new InternalRxmtLsrPacket(ch);
1487 exServiceRxmtLsr = Executors.newSingleThreadScheduledExecutor();
1488 exServiceRxmtLsr.scheduleAtFixedRate(rxmtLsrPacketTask, retransmitIntrvl,
1489 retransmitIntrvl, TimeUnit.SECONDS);
1490 rxmtLsrTimerScheduled = true;
1491 }
1492 }
1493
1494 /**
1495 * Stops Ls request retransmission executor task.
1496 */
sunishvkf7c56552016-07-18 16:02:39 +05301497 public void stopRxMtLsrTimer() {
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301498 if (rxmtLsrTimerScheduled) {
1499 exServiceRxmtLsr.shutdown();
1500 rxmtLsrTimerScheduled = false;
1501 }
1502 }
1503
1504 /**
1505 * Gets the last sent DdPacket.
1506 *
1507 * @return DdPacket instance
1508 */
1509 public DdPacket lastDdPacket() {
1510 return lastDdPacket;
1511 }
1512
1513 /**
1514 * Sets the last sent DdPacket.
1515 *
1516 * @param lastDdPacket DdPacket instance
1517 */
1518 public void setLastDdPacket(DdPacket lastDdPacket) {
1519 this.lastDdPacket = lastDdPacket;
1520 }
1521
1522 /**
1523 * Gets neighbor id.
1524 *
1525 * @return neighbor id
1526 */
1527 public Ip4Address neighborId() {
1528 return neighborId;
1529 }
1530
1531 /**
1532 * Sets the neighbor id.
1533 *
1534 * @param neighborId neighbor id
1535 */
1536 public void setNeighborId(Ip4Address neighborId) {
1537 this.neighborId = neighborId;
1538 }
1539
1540 /**
1541 * Gets the neighbor DR address.
1542 *
1543 * @return neighbor DR address
1544 */
1545 public Ip4Address neighborDr() {
1546 return neighborDr;
1547 }
1548
1549 /**
1550 * Sets the neighbor DR address.
1551 *
1552 * @param neighborDr neighbor DR address
1553 */
1554 public void setNeighborDr(Ip4Address neighborDr) {
1555 this.neighborDr = neighborDr;
1556 }
1557
1558 /**
1559 * Gets the neighbor BDR address.
1560 *
1561 * @return neighbor BDR address
1562 */
1563 public Ip4Address neighborBdr() {
1564 return neighborBdr;
1565 }
1566
1567 /**
1568 * Sets the neighbor BDR address.
1569 *
1570 * @param neighborBdr neighbor BDR address
1571 */
1572 public void setNeighborBdr(Ip4Address neighborBdr) {
1573 this.neighborBdr = neighborBdr;
1574 }
1575
1576 /**
1577 * Gets router priority.
1578 *
1579 * @return router priority
1580 */
1581 public int routerPriority() {
1582 return routerPriority;
1583 }
1584
1585 /**
1586 * Sets router priority.
1587 *
1588 * @param routerPriority router priority
1589 */
1590 public void setRouterPriority(int routerPriority) {
1591 this.routerPriority = routerPriority;
1592 }
1593
1594 /**
1595 * Gets the options value.
1596 *
1597 * @return options value
1598 */
1599 public int options() {
1600 return options;
1601 }
1602
1603 /**
1604 * Sets the options value.
1605 *
1606 * @param options options value
1607 */
1608 public void setOptions(int options) {
1609 this.options = options;
1610 }
1611
1612 /**
1613 * Gets the DD sequence number.
1614 *
1615 * @return DD sequence number
1616 */
1617 public long ddSeqNum() {
1618 return ddSeqNum;
1619 }
1620
1621 /**
1622 * Sets the DD sequence number.
1623 *
1624 * @param ddSeqNum DD sequence number
1625 */
1626 public void setDdSeqNum(long ddSeqNum) {
1627 this.ddSeqNum = ddSeqNum;
1628 }
1629
1630 /**
1631 * Gets neighbor is master or not.
1632 *
1633 * @return true if neighbor is master else false
1634 */
1635 public int isMaster() {
1636 return isMaster;
1637 }
1638
1639 /**
1640 * Gets the last sent DD Packet.
1641 *
1642 * @return last sent DD Packet
1643 */
1644 public DdPacket lastSentDdPacket() {
1645 return lastSentDdPacket;
1646 }
1647
1648 /**
1649 * Sets the last sent DD Packet.
1650 *
1651 * @param lastSentDdPacket last sent DD Packet
1652 */
1653 public void setLastSentDdPacket(DdPacket lastSentDdPacket) {
1654 this.lastSentDdPacket = lastSentDdPacket;
1655 }
1656
1657 /**
1658 * Gets the last sent Ls Request Packet.
1659 *
1660 * @return last sent Ls Request Packet
1661 */
1662 public LsRequest getLastSentLsrPacket() {
1663 return lastSentLsrPacket;
1664 }
1665
1666 /**
1667 * Sets the last sent Ls Request Packet.
1668 *
1669 * @param lastSentLsrPacket last sent Ls Request Packet
1670 */
1671 public void setLastSentLsrPacket(LsRequest lastSentLsrPacket) {
1672 this.lastSentLsrPacket = lastSentLsrPacket;
1673 }
1674
1675 /**
1676 * Gets the neighbors state.
1677 *
1678 * @return neighbors state
1679 */
1680 public OspfNeighborState getState() {
1681 return state;
1682 }
1683
1684 /**
1685 * Sets the neighbors state.
1686 *
1687 * @param state neighbors state
1688 */
1689 public void setState(OspfNeighborState state) {
1690 this.state = state;
1691 }
1692
1693 /**
1694 * Sets neighbor is master or not.
1695 *
1696 * @param isMaster neighbor is master or not
1697 */
1698 public void setIsMaster(int isMaster) {
1699 this.isMaster = isMaster;
1700 }
1701
1702 /**
1703 * Gets the ls request list.
1704 *
1705 * @return ls request list
1706 */
1707 public Hashtable getLsReqList() {
1708 return lsReqList;
1709 }
1710
1711 /**
1712 * Gets the reTxList instance.
1713 *
1714 * @return reTxList instance
1715 */
1716 public Map getReTxList() {
1717 return reTxList;
1718 }
1719
1720 /**
1721 * Gets the pending re transmit list.
1722 *
1723 * @return pendingReTxList instance
1724 */
1725 public Map<String, OspfLsa> getPendingReTxList() {
1726 return pendingReTxList;
1727 }
1728
sunishvkf7c56552016-07-18 16:02:39 +05301729 /**
1730 * Gets message as bytes.
1731 *
1732 * @param ospfMessage OSPF message
1733 * @return OSPF message
1734 */
1735 private byte[] getMessage(OspfMessage ospfMessage) {
1736 OspfMessageWriter messageWriter = new OspfMessageWriter();
1737 if (((OspfInterfaceImpl) ospfInterface).state().equals(OspfInterfaceState.POINT2POINT)) {
1738 ospfMessage.setDestinationIp(OspfUtil.ALL_SPF_ROUTERS);
1739 }
1740 return (messageWriter.getMessage(ospfMessage, ospfInterface.interfaceIndex(),
1741 ((OspfInterfaceImpl) ospfInterface).state().value()));
1742 }
1743
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301744
1745 /**
1746 * Represents a Task which will do an inactivity time check.
1747 */
1748 private class InternalInactivityTimeCheck implements Runnable {
1749 /**
1750 * Constructor.
1751 */
1752 InternalInactivityTimeCheck() {
1753 }
1754
1755 @Override
1756 public void run() {
1757 try {
1758 log.debug("Neighbor Not Heard till the past router dead interval .");
1759 neighborDown();
1760 } catch (Exception e) {
1761 log.debug("Exception at inactivity time check...!!!");
1762 }
1763 }
1764 }
1765
1766 /**
1767 * Task which re transmits DdPacket every configured time interval.
1768 */
1769 private class InternalRxmtDdPacket implements Runnable {
1770 Channel ch;
1771
1772 /**
1773 * Creates an instance or Re transmit DD packet timer.
1774 *
1775 * @param ch netty channel instance
1776 */
1777 InternalRxmtDdPacket(Channel ch) {
1778 this.ch = ch;
1779 }
1780
1781 @Override
1782 public void run() {
1783 if ((ch != null) && ch.isConnected()) {
1784 DdPacket ddPacket = lastSentDdPacket();
sunishvkf7c56552016-07-18 16:02:39 +05301785 byte[] messageToWrite = getMessage(ddPacket);
1786 ch.write(messageToWrite);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301787 log.debug("Re-Transmit DD Packet .");
1788 } else {
1789 log.debug(
1790 "Re-Transmit DD Packet failed. Channel not connected..");
1791 }
1792 }
1793 }
1794
1795 /**
1796 * Task which re transmits Ls request Packet every configured time interval.
1797 */
1798 private class InternalRxmtLsrPacket implements Runnable {
1799 Channel ch;
1800
1801 /**
1802 * Creates an instance or Re transmit LS Request packet timer.
1803 *
1804 * @param ch netty channel instance
1805 */
1806 InternalRxmtLsrPacket(Channel ch) {
1807 this.ch = ch;
1808 }
1809
1810 @Override
1811 public void run() {
1812 if ((ch != null) && ch.isConnected()) {
1813 LsRequest lsrPacket = getLastSentLsrPacket();
sunishvkf7c56552016-07-18 16:02:39 +05301814 byte[] messageToWrite = getMessage(lsrPacket);
1815 ch.write(messageToWrite);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301816 log.debug("Re-Transmit LSRequest Packet .");
1817 } else {
1818 log.debug(
1819 "Re-Transmit LSRequest failed. Channel not connected..");
1820 }
1821 }
1822 }
1823
1824 /**
1825 * Task which transmits Ls update Packet based on the re transmit list.
1826 * every configured time interval.
1827 */
1828 private class InternalFloodingTask implements Runnable {
1829 Channel channel;
1830
1831 /**
1832 * Creates an instance or Flooding task.
1833 *
1834 * @param ch netty channel instance
1835 */
1836 InternalFloodingTask(Channel ch) {
1837 this.channel = ch;
1838 }
1839
1840 @Override
1841 public void run() {
1842 if ((channel != null) && channel.isConnected()) {
1843
1844 if ((pendingReTxList != null) && (pendingReTxList.size() > 0)) {
1845 List<LsUpdate> lsUpdateList = buildLsUpdate(pendingReTxList);
1846
1847 for (LsUpdate lsupdate : lsUpdateList) {
1848 //Pending for acknowledge directly sent it to neighbor
1849 lsupdate.setDestinationIp(neighborIpAddr);
sunishvkf7c56552016-07-18 16:02:39 +05301850 byte[] messageToWrite = getMessage(lsupdate);
1851 channel.write(messageToWrite);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301852 }
1853 }
1854
1855 if ((reTxList != null) && (reTxList.size() > 0)) {
1856 List<LsUpdate> lsUpdateList = buildLsUpdate(reTxList);
1857
1858 for (LsUpdate lsupdate : lsUpdateList) {
1859 //set the destination
1860 if ((((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.DR) ||
1861 (((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.POINT2POINT)) {
1862 lsupdate.setDestinationIp(OspfUtil.ALL_SPF_ROUTERS);
1863 } else if (((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.DROTHER ||
1864 (((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.BDR)) {
1865 lsupdate.setDestinationIp(neighborDr);
1866 }
sunishvkf7c56552016-07-18 16:02:39 +05301867 byte[] messageToWrite = getMessage(lsupdate);
1868 channel.write(messageToWrite);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301869 }
1870 }
1871 }
1872 }
1873
1874 /**
1875 * Builds the LsUpdate for flooding.
1876 *
1877 * @param txList list contains LSAs
1878 * @return list of LsUpdate instances
1879 */
1880 private List buildLsUpdate(Map<String, OspfLsa> txList) {
1881 List<LsUpdate> lsUpdateList = new ArrayList<>();
1882 ListIterator itr = new ArrayList(txList.keySet()).listIterator();
1883 while (itr.hasNext()) {
1884 LsUpdate lsupdate = new LsUpdate();
1885 // seting OSPF Header
1886 lsupdate.setOspfVer(OspfUtil.OSPF_VERSION);
1887 lsupdate.setOspftype(OspfPacketType.LSUPDATE.value());
1888 lsupdate.setRouterId(ospfArea.routerId());
1889 lsupdate.setAreaId(ospfArea.areaId());
1890 lsupdate.setAuthType(OspfUtil.NOT_ASSIGNED);
1891 lsupdate.setAuthentication(OspfUtil.NOT_ASSIGNED);
1892 lsupdate.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
1893 lsupdate.setChecksum(OspfUtil.NOT_ASSIGNED);
1894
1895 //limit to mtu
1896 int currentLength = OspfUtil.OSPF_HEADER_LENGTH + OspfUtil.FOUR_BYTES;
1897 int maxSize = ospfInterface.mtu() -
1898 OspfUtil.LSA_HEADER_LENGTH; // subtract a normal IP header.
1899
1900 int noLsa = 0;
1901 while (itr.hasNext()) {
1902
1903 String key = (String) itr.next();
1904 OspfLsa lsa = txList.get(key);
1905 if ((lsa.age() + OspfParameters.INFTRA_NS_DELAY) >= OspfParameters.MAXAGE) {
1906 ((LsaHeader) lsa.lsaHeader()).setAge(OspfParameters.MAXAGE);
1907 } else {
1908 ((LsaHeader) lsa.lsaHeader()).setAge(lsa.age() + OspfParameters.INFTRA_NS_DELAY);
1909 }
1910
1911 if ((currentLength + ((LsaHeader) lsa.lsaHeader()).lsPacketLen()) >= maxSize) {
1912 itr.previous();
1913 break;
1914 }
1915 log.debug("FloodingTimer::LSA Type::{}, Header: {}, LSA: {}", lsa.getOspfLsaType(),
1916 lsa.lsaHeader(), lsa);
1917
1918 if (lsa != null) {
1919 lsupdate.addLsa(lsa);
1920 noLsa++;
1921 currentLength = currentLength + ((LsaHeader) lsa.lsaHeader()).lsPacketLen();
1922 }
1923 log.debug("FloodingTimer::Removing key {}", key);
1924 if (txList.equals(reTxList)) {
1925 reTxList.remove(key);
1926 pendingReTxList.put(key, lsa);
1927 }
1928 }
1929 //set number of lsa's
1930 lsupdate.setNumberOfLsa(noLsa);
1931 lsUpdateList.add(lsupdate);
1932 }
1933 return lsUpdateList;
1934 }
1935 }
Ray Milkey0bb1e102016-11-10 14:51:27 -08001936}