blob: ff3f75b9bf73b652f71204fd9bacbab2b6a846b8 [file] [log] [blame]
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002* Copyright 2016-present Open Networking Foundation
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 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -0800221 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530222 public Ip4Address neighborIpAddr() {
223 return neighborIpAddr;
224 }
225
226 /**
227 * Gets the neighbor is opaque enabled or not.
228 *
229 * @return true if the neighbor is opaque enabled else false.
230 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -0800231 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530232 public boolean isOpaqueCapable() {
233 return isOpaqueCapable;
234 }
235
236 /**
237 * Sets the neighbor is opaque enabled or not.
238 *
239 * @param isOpaqueCapable true if the neighbor is opaque enabledelse false
240 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -0800241 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530242 public void setIsOpaqueCapable(boolean isOpaqueCapable) {
243 this.isOpaqueCapable = isOpaqueCapable;
244 }
245
246 /**
sunishvkf7c56552016-07-18 16:02:39 +0530247 * Sets router dead interval.
248 *
249 * @param routerDeadInterval router dead interval
250 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -0800251 @Override
sunishvkf7c56552016-07-18 16:02:39 +0530252 public void setRouterDeadInterval(int routerDeadInterval) {
253 this.routerDeadInterval = routerDeadInterval;
254 }
255
256 /**
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530257 * Have seen a Neighbor, but the Neighbor doesn't know about me.
258 *
259 * @param ospfHello Hello Packet instance
260 * @param channel netty channel instance
261 */
262 public void oneWayReceived(OspfMessage ospfHello, Channel channel) {
263 log.debug("OSPFNbr::oneWayReceived...!!!");
264 stopInactivityTimeCheck();
265 startInactivityTimeCheck();
266
267 if (state == OspfNeighborState.ATTEMPT) {
268 state = OspfNeighborState.INIT;
269 } else if (state == OspfNeighborState.DOWN) {
270 state = OspfNeighborState.INIT;
271 }
272
273 if (state.getValue() >= OspfNeighborState.TWOWAY.getValue()) {
274 state = OspfNeighborState.INIT;
275 failedTxList.clear();
276 ddSummaryList.clear();
277 lsReqList.clear();
278 }
279 }
280
281 /**
282 * Called when a DD OSPFMessage is received while state was INIT.
283 *
284 * @param ospfMessage ospf message instance
285 * @param channel netty channel instance
286 * @throws Exception might throws exception
287 */
288 public void twoWayReceived(OspfMessage ospfMessage, Channel channel) throws Exception {
289 log.debug("OSPFNbr::twoWayReceived...!!!");
290 stopInactivityTimeCheck();
291 startInactivityTimeCheck();
292 startFloodingTimer(channel);
293
294 OspfPacketHeader packet = (OspfPacketHeader) ospfMessage;
295 if (state.getValue() <= OspfNeighborState.TWOWAY.getValue()) {
296 if (formAdjacencyOrNot()) {
297 state = OspfNeighborState.EXSTART;
298
299 ddSeqNum++;
300 DdPacket ddPacket = new DdPacket();
301 // seting OSPF Header
302 ddPacket.setOspfVer(OspfUtil.OSPF_VERSION);
303 ddPacket.setOspftype(OspfPacketType.DD.value());
304 ddPacket.setRouterId(ospfArea.routerId());
305 ddPacket.setAreaId(ospfArea.areaId());
306 ddPacket.setAuthType(OspfUtil.NOT_ASSIGNED);
307 ddPacket.setAuthentication(OspfUtil.NOT_ASSIGNED);
308 ddPacket.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
309 ddPacket.setChecksum(OspfUtil.NOT_ASSIGNED);
310 boolean isOpaqueEnabled = ospfArea.isOpaqueEnabled();
311 if (isOpaqueEnabled) {
312 ddPacket.setOptions(ospfArea.opaqueEnabledOptions());
313 } else {
314 ddPacket.setOptions(ospfArea.options());
315 }
316 ddPacket.setIsInitialize(OspfUtil.INITIALIZE_SET);
317 ddPacket.setIsMore(OspfUtil.MORE_SET);
318 ddPacket.setIsMaster(OspfUtil.IS_MASTER);
319 ddPacket.setImtu(ospfInterface.mtu());
320 ddPacket.setSequenceNo(ddSeqNum);
321
322 setLastSentDdPacket(ddPacket);
323 rxmtDdPacketTask = new InternalRxmtDdPacket(channel);
324 startRxMtDdTimer(channel);
325 //setting destination ip
326 ddPacket.setDestinationIp(packet.sourceIp());
sunishvkf7c56552016-07-18 16:02:39 +0530327 byte[] messageToWrite = getMessage(ddPacket);
328 channel.write(messageToWrite);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530329 } else {
330 state = OspfNeighborState.TWOWAY;
331 }
332 }
333 }
334
335 /**
336 * Checks whether to form adjacency or not.
337 *
338 * @return true indicates form adjacency, else false
339 */
340 private boolean formAdjacencyOrNot() {
341 boolean formAdjacency = false;
342
343 if (ospfInterface.interfaceType() == OspfInterfaceType.POINT_TO_POINT.value()) {
344 formAdjacency = true;
345 } else if (ospfInterface.interfaceType() == OspfInterfaceType.BROADCAST.value()) {
346 if (ospfInterface.ipAddress().equals(this.neighborDr) ||
347 ospfInterface.ipAddress().equals(this.neighborBdr)) {
348 formAdjacency = true;
349 } else if (neighborBdr.equals(neighborIpAddr) ||
350 neighborDr.equals(neighborIpAddr)) {
351 formAdjacency = true;
352 }
353 }
354
355 log.debug("FormAdjacencyOrNot - neighborDR: {}, neighborBDR: {}, neighborIPAddr: {}, formAdjacencyOrNot {}",
356 neighborDr, neighborBdr, neighborIpAddr, formAdjacency);
357
358 return formAdjacency;
359 }
360
361 /**
362 * At this point Master/Slave relationship is definitely established.
363 * DD sequence numbers have been exchanged.
364 * This is the begin of sending/receiving of DD OSPFMessages.
365 *
366 * @param ospfMessage OSPF message instance
367 * @param neighborIsMaster neighbor is master or slave
368 * @param payload contains the LSAs to add in Dd Packet
369 * @param ch netty channel instance
370 * @throws Exception might throws exception
371 */
372 public void negotiationDone(OspfMessage ospfMessage,
373 boolean neighborIsMaster, List payload, Channel ch) throws Exception {
374 stopRxMtDdTimer();
375 OspfPacketHeader packet = (OspfPacketHeader) ospfMessage;
376 DdPacket ddPacketForCheck = (DdPacket) packet;
377 if (ddPacketForCheck.isOpaqueCapable()) {
378 OspfLsdb database = ospfArea.database();
379 List opaqueLsas = database.getAllLsaHeaders(true, true);
380 Iterator iterator = opaqueLsas.iterator();
381 while (iterator.hasNext()) {
382 OspfLsa ospfLsa = (OspfLsa) iterator.next();
383 if (ospfLsa.getOspfLsaType() == OspfLsaType.AREA_LOCAL_OPAQUE_LSA) {
384 OpaqueLsa10 opaqueLsa10 = (OpaqueLsa10) ospfLsa;
385 topLevelTlvs = opaqueLsa10.topLevelValues();
386 }
387 }
388 }
389 if (state == OspfNeighborState.EXSTART) {
390 state = OspfNeighborState.EXCHANGE;
391 boolean excludeMaxAgeLsa = true;
392 //list of contents of area wise LSA
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -0800393 ddSummaryList = ospfArea.getLsaHeaders(excludeMaxAgeLsa, isOpaqueCapable);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530394
395 if (neighborIsMaster) {
396 processLsas(payload);
397 // ...construct new DD Packet...
398 DdPacket ddPacket = new DdPacket();
399 // setting OSPF Header
400 ddPacket.setOspfVer(OspfUtil.OSPF_VERSION);
401 ddPacket.setOspftype(OspfPacketType.DD.value());
402 ddPacket.setRouterId(ospfArea.routerId());
403 ddPacket.setAreaId(ospfArea.areaId());
404 ddPacket.setAuthType(OspfUtil.NOT_ASSIGNED);
405 ddPacket.setAuthentication(OspfUtil.NOT_ASSIGNED);
406 ddPacket.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
407 ddPacket.setChecksum(OspfUtil.NOT_ASSIGNED);
408 boolean isOpaqueEnabled = ospfArea.isOpaqueEnabled();
409 if (isOpaqueEnabled && isOpaqueCapable) {
410 ddPacket.setOptions(ospfArea.opaqueEnabledOptions());
411 } else {
412 ddPacket.setOptions(ospfArea.options());
413 }
414 ddPacket.setIsInitialize(OspfUtil.INITIALIZE_NOTSET);
415 ddPacket.setIsMore(OspfUtil.MORE_NOTSET);
416 ddPacket.setIsMaster(OspfUtil.NOT_MASTER);
417 ddPacket.setImtu(ospfInterface.mtu());
418 ddPacket.setSequenceNo(ddSeqNum);
419 //setting the destination
420 ddPacket.setDestinationIp(packet.sourceIp());
421 setLastSentDdPacket(ddPacket);
422 getIsMoreBit();
423
sunishvkf7c56552016-07-18 16:02:39 +0530424 byte[] messageToWrite = getMessage(lastSentDdPacket);
425 ch.write(messageToWrite);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530426 } else {
427 // process LSA Vector's List, Add it to LSRequestList.
428 processLsas(payload);
429 DdPacket ddPacket = new DdPacket();
430 // setting OSPF Header
431 ddPacket.setOspfVer(OspfUtil.OSPF_VERSION);
432 ddPacket.setOspftype(OspfPacketType.DD.value());
433 ddPacket.setRouterId(ospfArea.routerId());
434 ddPacket.setAreaId(ospfArea.areaId());
435 ddPacket.setAuthType(OspfUtil.NOT_ASSIGNED);
436 ddPacket.setAuthentication(OspfUtil.NOT_ASSIGNED);
437 ddPacket.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
438 ddPacket.setChecksum(OspfUtil.NOT_ASSIGNED);
439 boolean isOpaqueEnabled = ospfArea.isOpaqueEnabled();
440 if (isOpaqueEnabled && isOpaqueCapable) {
441 ddPacket.setOptions(ospfArea.opaqueEnabledOptions());
442 } else {
443 ddPacket.setOptions(ospfArea.options());
444 }
445 ddPacket.setIsInitialize(OspfUtil.INITIALIZE_NOTSET);
446 ddPacket.setIsMore(OspfUtil.MORE_NOTSET);
447 ddPacket.setIsMaster(OspfUtil.IS_MASTER);
448 ddPacket.setImtu(ospfInterface.mtu());
449 ddPacket.setSequenceNo(ddSeqNum);
450 setLastSentDdPacket(ddPacket);
451 getIsMoreBit();
452 ddPacket.setDestinationIp(packet.sourceIp());
sunishvkf7c56552016-07-18 16:02:39 +0530453 byte[] messageToWrite = getMessage(lastSentDdPacket);
454 ch.write(messageToWrite);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530455 startRxMtDdTimer(ch);
456 }
457 }
458 }
459
460 /**
461 * Process the LSA Headers received in the last received Database Description OSPFMessage.
462 *
463 * @param ddPayload LSA headers to process
464 * @throws Exception might throws exception
465 */
466 public void processLsas(List ddPayload) throws Exception {
467 log.debug("OSPFNbr::processLsas...!!!");
468 OspfLsa nextLsa;
469 Iterator lsas = ddPayload.iterator();
470 while (lsas.hasNext()) {
471 nextLsa = (OspfLsa) lsas.next();
472 // check LSA Type.
473 if (((nextLsa.getOspfLsaType().value() > OspfLsaType.EXTERNAL_LSA.value()) &&
474 (nextLsa.getOspfLsaType().value() < OspfLsaType.LINK_LOCAL_OPAQUE_LSA.value())) ||
475 (nextLsa.getOspfLsaType().value() > OspfLsaType.AS_OPAQUE_LSA.value())) {
476 // unknown lsType found!
477 seqNumMismatch("LS Type found was unknown.");
478 return;
479 }
480
481 if ((nextLsa.getOspfLsaType() == OspfLsaType.EXTERNAL_LSA) &&
482 !ospfArea.isExternalRoutingCapability()) {
483 // LSA is external and the Area has no external lsa capability
484 seqNumMismatch("External LSA found although area is stub.");
485 return;
486 }
487
488 LsaWrapper lsaHasInstance = ospfArea.lsaLookup(nextLsa);
489 if (lsaHasInstance == null) {
490 lsReqList.put(((OspfAreaImpl) ospfArea).getLsaKey((LsaHeader) nextLsa), nextLsa);
491 } else {
492 String isNew = ((OspfAreaImpl) ospfArea).isNewerOrSameLsa(nextLsa,
493 lsaHasInstance.ospfLsa());
494 if (isNew.equals("latest")) {
495 lsReqList.put(((OspfAreaImpl) ospfArea).getLsaKey((LsaHeader) nextLsa), nextLsa);
496 }
497 }
498 }
499 }
500
501 /**
502 * Handles sequence number mis match event.
503 *
504 * @param reason a string represents the mismatch reason
505 * @return OSPF message instance
506 * @throws Exception might throws exception
507 */
508 public OspfMessage seqNumMismatch(String reason) throws Exception {
509 log.debug("OSPFNbr::seqNumMismatch...{} ", reason);
510 stopRxMtDdTimer();
511
512 if (state.getValue() >= OspfNeighborState.EXCHANGE.getValue()) {
513 /* if (state == OspfNeighborState.FULL) {
514 ospfArea.refreshArea(ospfInterface);
515 }*/
516
517 state = OspfNeighborState.EXSTART;
518 lsReqList.clear();
519 ddSummaryList.clear();
520 //increment the dd sequence number
521 ddSeqNum++;
522
523 DdPacket ddPacket = new DdPacket();
524 // seting OSPF Header
525 ddPacket.setOspfVer(OspfUtil.OSPF_VERSION);
526 ddPacket.setOspftype(OspfPacketType.DD.value());
527 ddPacket.setRouterId(ospfArea.routerId());
528 ddPacket.setAreaId(ospfArea.areaId());
529 ddPacket.setAuthType(OspfUtil.NOT_ASSIGNED);
530 ddPacket.setAuthentication(OspfUtil.NOT_ASSIGNED);
531 ddPacket.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
532 ddPacket.setChecksum(OspfUtil.NOT_ASSIGNED);
533 boolean isOpaqueEnabled = ospfArea.isOpaqueEnabled();
534 if (isOpaqueEnabled) {
535 ddPacket.setOptions(ospfArea.opaqueEnabledOptions());
536 } else {
537 ddPacket.setOptions(ospfArea.options());
538 }
539 ddPacket.setIsInitialize(OspfUtil.INITIALIZE_SET);
540 ddPacket.setIsMore(OspfUtil.MORE_SET);
541 ddPacket.setIsMaster(OspfUtil.IS_MASTER);
542 ddPacket.setImtu(ospfInterface.mtu());
543 ddPacket.setSequenceNo(ddSeqNum);
544
545 setLastSentDdPacket(ddPacket);
546 //setting destination ip
547 ddPacket.setDestinationIp(neighborIpAddr());
548 setLastSentDdPacket(ddPacket);
549
550 return ddPacket;
551 }
552
553 return null;
554 }
555
556 /**
557 * Called if a LS Request has been received for an LSA which is not contained in the database.
558 * This indicates an error in the Database Exchange process.
559 * Actions to be performed are the same as in seqNumMismatch.
560 * In addition, stop the possibly activated re transmission timer.
561 *
562 * @param ch netty channel instance
Ray Milkey0bb1e102016-11-10 14:51:27 -0800563 * @throws Exception on error
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530564 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -0800565 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530566 public void badLSReq(Channel ch) throws Exception {
567 log.debug("OSPFNbr::badLSReq...!!!");
568
569 if (state.getValue() >= OspfNeighborState.EXCHANGE.getValue()) {
570 if (state == OspfNeighborState.FULL) {
571 ospfArea.refreshArea(ospfInterface);
572 }
573
574 stopRxMtDdTimer();
575 state = OspfNeighborState.EXSTART;
576
577 lsReqList.clear();
578 ddSummaryList.clear();
579 reTxList.clear();
580 //increment the dd sequence number
581 isMaster = OspfUtil.IS_MASTER;
582 ddSeqNum++;
583 DdPacket ddPacket = new DdPacket();
584 // seting OSPF Header
585 ddPacket.setOspfVer(OspfUtil.OSPF_VERSION);
586 ddPacket.setOspftype(OspfPacketType.DD.value());
587 ddPacket.setRouterId(ospfArea.routerId());
588 ddPacket.setAreaId(ospfArea.areaId());
589 ddPacket.setAuthType(OspfUtil.NOT_ASSIGNED);
590 ddPacket.setAuthentication(OspfUtil.NOT_ASSIGNED);
591 ddPacket.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
592 ddPacket.setChecksum(OspfUtil.NOT_ASSIGNED);
593
594 // setting DD Body
595 boolean isOpaqueEnabled = ospfArea.isOpaqueEnabled();
596 if (isOpaqueEnabled && this.isOpaqueCapable) {
597 ddPacket.setOptions(ospfArea.opaqueEnabledOptions());
598 } else {
599 ddPacket.setOptions(ospfArea.options());
600 }
601 ddPacket.setIsInitialize(OspfUtil.INITIALIZE_SET);
602 ddPacket.setIsMore(OspfUtil.MORE_SET);
603 ddPacket.setIsMaster(OspfUtil.IS_MASTER);
604 ddPacket.setImtu(ospfInterface.mtu());
605 ddPacket.setSequenceNo(ddSeqNum);
606
607 rxmtDdPacketTask = new InternalRxmtDdPacket(ch);
608 startRxMtDdTimer(ch);
609
610 //setting destination ip
611 ddPacket.setDestinationIp(neighborIpAddr());
612 setLastSentDdPacket(ddPacket);
sunishvkf7c56552016-07-18 16:02:39 +0530613 byte[] messageToWrite = getMessage(ddPacket);
614 ch.write(messageToWrite);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530615 }
616 }
617
618 /**
619 * Called if state is EXCHANGE. This method is executed every time a DD Packets arrives.
620 * When the last Packet arrives, it transfers the state into LOADING or FULL
621 *
622 * @param neighborIsMaster true if neighbor is master else false
623 * @param dataDescPkt DdPacket instance
624 * @param ch netty channel instance
625 * @throws Exception might throws exception
626 */
627 public void processDdPacket(boolean neighborIsMaster, DdPacket dataDescPkt,
628 Channel ch) throws Exception {
629 log.debug("OSPFNbr::neighborIsMaster.{}", neighborIsMaster);
630
631 if (!neighborIsMaster) {
632 stopRxMtDdTimer();
633 ddSeqNum++;
634 processLsas(dataDescPkt.getLsaHeaderList());
635 if ((ddSummaryList.isEmpty()) &&
636 (dataDescPkt.isMore() == OspfUtil.MORE_NOTSET)) {
637 log.debug(
638 "OSPFNbr::ddSummaryList is empty and dataDescPkt.isMore is zero..!!!");
639 // generate the neighbor event ExchangeDone.
640 exchangeDone(dataDescPkt, ch);
641 } else {
642 log.debug("OSPFNbr::ddSummaryList is present...!!!");
643 // send a new Database Description Packet to the slave.
644 DdPacket ddPacket = new DdPacket();
645 // seting OSPF Header
646 ddPacket.setOspfVer(OspfUtil.OSPF_VERSION);
647 ddPacket.setOspftype(OspfPacketType.DD.value());
648 ddPacket.setRouterId(ospfArea.routerId());
649 ddPacket.setAreaId(ospfArea.areaId());
650 ddPacket.setAuthType(OspfUtil.NOT_ASSIGNED);
651 ddPacket.setAuthentication(OspfUtil.NOT_ASSIGNED);
652 ddPacket.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
653 ddPacket.setChecksum(OspfUtil.NOT_ASSIGNED);
654 // setting DD Body
655 boolean isOpaqueEnabled = ospfArea.isOpaqueEnabled();
656 if (isOpaqueEnabled && isOpaqueCapable) {
657 ddPacket.setOptions(ospfArea.opaqueEnabledOptions());
658 } else {
659 ddPacket.setOptions(ospfArea.options());
660 }
661 ddPacket.setIsInitialize(OspfUtil.INITIALIZE_NOTSET);
662 ddPacket.setIsMore(OspfUtil.MORE_NOTSET);
663 ddPacket.setIsMaster(OspfUtil.IS_MASTER);
664 ddPacket.setImtu(ospfInterface.mtu());
665 ddPacket.setSequenceNo(ddSeqNum);
666
667 setLastSentDdPacket(ddPacket);
668 getIsMoreBit();
669 //Set the destination IP Address
670 ddPacket.setDestinationIp(dataDescPkt.sourceIp());
sunishvkf7c56552016-07-18 16:02:39 +0530671 byte[] messageToWrite = getMessage(lastSentDdPacket());
672 ch.write(messageToWrite);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530673
674 startRxMtDdTimer(ch);
675 }
676 } else {
677 log.debug("OSPFNbr::neighborIsMaster is master...!!!");
678 ddSeqNum = dataDescPkt.sequenceNo();
679 processLsas(dataDescPkt.getLsaHeaderList());
680
681 DdPacket ddPacket = new DdPacket();
682 // seting OSPF Header
683 ddPacket.setOspfVer(OspfUtil.OSPF_VERSION);
684 ddPacket.setOspftype(OspfPacketType.DD.value());
685 ddPacket.setRouterId(ospfArea.routerId());
686 ddPacket.setAreaId(ospfArea.areaId());
687 ddPacket.setAuthType(OspfUtil.NOT_ASSIGNED);
688 ddPacket.setAuthentication(OspfUtil.NOT_ASSIGNED);
689 ddPacket.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
690 ddPacket.setChecksum(OspfUtil.NOT_ASSIGNED);
691 // setting DD Body
692 boolean isOpaqueEnabled = ospfArea.isOpaqueEnabled();
693 if (isOpaqueEnabled && this.isOpaqueCapable) {
694 ddPacket.setOptions(ospfArea.opaqueEnabledOptions());
695 } else {
696 ddPacket.setOptions(ospfArea.options());
697 }
698 ddPacket.setIsInitialize(OspfUtil.INITIALIZE_NOTSET);
699 ddPacket.setIsMore(OspfUtil.MORE_NOTSET);
700 ddPacket.setIsMaster(OspfUtil.NOT_MASTER);
701 ddPacket.setImtu(ospfInterface.mtu());
702 ddPacket.setSequenceNo(ddSeqNum);
703 setLastSentDdPacket(ddPacket);
704 getIsMoreBit();
705
706 if ((ddPacket.isMore() == OspfUtil.MORE_NOTSET) &&
707 (dataDescPkt.isMore() == OspfUtil.MORE_NOTSET)) {
708 // generate the neighbor event ExchangeDone.
709 exchangeDone(dataDescPkt, ch);
710 }
711
712 ddPacket.setDestinationIp(dataDescPkt.sourceIp());
sunishvkf7c56552016-07-18 16:02:39 +0530713 byte[] messageToWrite = getMessage(ddPacket);
714 ch.write(messageToWrite);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530715 }
716 }
717
718 /**
719 * Sets the more bit in stored, last sent DdPacket.
720 */
721 private void getIsMoreBit() {
722 DdPacket ddPacket = lastSentDdPacket();
723 int count = ddSummaryList.size();
724
725 if (!ddSummaryList.isEmpty()) {
726 Iterator itr = ddSummaryList.iterator();
727 int currentLength = OspfUtil.DD_HEADER_LENGTH;
728 int maxSize = ospfInterface.mtu() - OspfUtil.LSA_HEADER_LENGTH; // subtract a normal IP header.
729 while (itr.hasNext()) {
730 if ((currentLength + OspfUtil.LSA_HEADER_LENGTH) > maxSize) {
731 break;
732 }
733
734 LsaHeader lsaHeader = (LsaHeader) itr.next();
735 ddPacket.addLsaHeader(lsaHeader);
736 currentLength = currentLength + OspfUtil.LSA_HEADER_LENGTH;
737 ddSummaryList.remove(lsaHeader);
738 count--;
739 }
740
741 if (count > 0) {
742 ddPacket.setIsMore(OspfUtil.MORE_SET);
743 } else {
744 ddPacket.setIsMore(OspfUtil.MORE_NOTSET);
745 }
746 }
747
748 setLastSentDdPacket(ddPacket);
749 }
750
751 /**
752 * At this point, the router has sent and received an entire sequence of DD packets.
753 * Now it must be determined whether the new state is FULL, or LS Request packets
754 * have to be send.
755 *
756 * @param message OSPF message instance
757 * @param ch netty channel handler
758 */
759 public void exchangeDone(OspfMessage message, Channel ch) {
760 log.debug("OSPFNbr::exchangeDone...!!!");
761 stopRxMtDdTimer();
762
763 OspfPacketHeader header = (OspfPacketHeader) message;
764
765 if (state == OspfNeighborState.EXCHANGE) {
766 if (lsReqList.isEmpty()) {
767 state = OspfNeighborState.FULL;
768 //handler.addDeviceInformation(this);
769 //handler.addLinkInformation(this, topLevelTlvs);
770 } else {
771 state = OspfNeighborState.LOADING;
772 LsRequest lsRequest = buildLsRequest();
773 //Setting the destination address
774 lsRequest.setDestinationIp(header.sourceIp());
sunishvkf7c56552016-07-18 16:02:39 +0530775 byte[] messageToWrite = getMessage(lsRequest);
776 ch.write(messageToWrite);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530777
778 setLastSentLsrPacket(lsRequest);
779 startRxMtLsrTimer(ch);
780 }
781 }
782 }
783
784 /**
785 * Builds LS Request.
786 *
787 * @return ls request instance
788 */
789 private LsRequest buildLsRequest() {
790 //send link state request packet to neighbor
791 //for recent lsa's which are not received in exchange state
792 LsRequest lsRequest = new LsRequest();
793 lsRequest.setOspfVer(OspfUtil.OSPF_VERSION);
794 lsRequest.setOspftype(OspfPacketType.LSREQUEST.value());
795 lsRequest.setRouterId(ospfArea.routerId());
796 lsRequest.setAreaId(ospfArea.areaId());
797 lsRequest.setAuthType(OspfUtil.NOT_ASSIGNED);
798 lsRequest.setAuthentication(OspfUtil.NOT_ASSIGNED);
799 lsRequest.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
800 lsRequest.setChecksum(OspfUtil.NOT_ASSIGNED);
801
802 Set lsaKeys = lsReqList.keySet();
803 Iterator itr = lsaKeys.iterator();
804
805 int currentLength = OspfUtil.OSPF_HEADER_LENGTH;
806 int maxSize = ospfInterface.mtu() -
807 OspfUtil.LSA_HEADER_LENGTH; // subtract a normal IP header.
808
809 while (itr.hasNext()) {
810 if ((currentLength + OspfUtil.LSREQUEST_LENGTH) >= maxSize) {
811 break;
812 }
813 LsRequestPacket lsRequestPacket = new LsRequestPacket();
814
815 String key = ((String) itr.next());
816 String[] lsaKey = key.split("-");
817 OspfLsa lsa = (OspfLsa) lsReqList.get(key);
818
819 lsRequestPacket.setLsType(Integer.valueOf(lsaKey[0]));
820 lsRequestPacket.setOwnRouterId(lsaKey[2]);
821
822 if (((lsa.getOspfLsaType().value() == OspfLsaType.AREA_LOCAL_OPAQUE_LSA.value()) ||
823 (lsa.getOspfLsaType().value() == OspfLsaType.LINK_LOCAL_OPAQUE_LSA.value())) ||
824 (lsa.getOspfLsaType().value() == OspfLsaType.AS_OPAQUE_LSA.value())) {
825 OpaqueLsaHeader header = (OpaqueLsaHeader) lsa;
826 byte[] opaqueIdBytes = OspfUtil.convertToTwoBytes(header.opaqueId());
827 lsRequestPacket.setLinkStateId(header.opaqueType() + "." + "0" + "." + opaqueIdBytes[0]
828 + "." + opaqueIdBytes[1]);
829 } else {
830 lsRequestPacket.setLinkStateId(lsaKey[1]);
831 }
832
833 lsRequest.addLinkStateRequests(lsRequestPacket);
834 currentLength = currentLength + OspfUtil.LSREQUEST_LENGTH;
835 }
836
837 return lsRequest;
838 }
839
840 /**
841 * Determines whether an adjacency should be established/maintained with the neighbor or not.
842 *
843 * @param ch netty channel instance
844 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -0800845 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530846 public void adjOk(Channel ch) {
847 log.debug("OSPFNbr::adjOk...!!!");
848 if (ospfInterface.interfaceType() != OspfInterfaceType.POINT_TO_POINT.value()) {
849 if (state == OspfNeighborState.TWOWAY) {
850 if (formAdjacencyOrNot()) {
851 state = OspfNeighborState.EXSTART;
852 //check for sequence number in lsdb
853 ddSeqNum++;
854
855 DdPacket ddPacket = new DdPacket();
856 // seting OSPF Header
857 ddPacket.setOspfVer(OspfUtil.OSPF_VERSION);
858 ddPacket.setOspftype(OspfPacketType.DD.value());
859 ddPacket.setRouterId(ospfArea.routerId());
860 ddPacket.setAreaId(ospfArea.areaId());
861 ddPacket.setAuthType(OspfUtil.NOT_ASSIGNED);
862 ddPacket.setAuthentication(OspfUtil.NOT_ASSIGNED);
863 ddPacket.setOspfPacLength(OspfUtil.NOT_ASSIGNED);
864 ddPacket.setChecksum(OspfUtil.NOT_ASSIGNED);
865
866 // setting DD Body
867 boolean isOpaqueEnabled = ospfArea.isOpaqueEnabled();
868 if (isOpaqueEnabled && this.isOpaqueCapable) {
869 ddPacket.setOptions(ospfArea.opaqueEnabledOptions());
870 } else {
871 ddPacket.setOptions(ospfArea.options());
872 }
873 ddPacket.setIsInitialize(OspfUtil.INITIALIZE_SET);
874 ddPacket.setIsMore(OspfUtil.MORE_SET);
875 ddPacket.setIsMaster(OspfUtil.IS_MASTER);
876 ddPacket.setImtu(ospfInterface.mtu());
877 ddPacket.setSequenceNo(ddSeqNum);
878 rxmtDdPacketTask = new InternalRxmtDdPacket(ch);
879 startRxMtDdTimer(ch);
880 //setting destination ip
881 ddPacket.setDestinationIp(neighborIpAddr());
882 setLastSentDdPacket(ddPacket);
sunishvkf7c56552016-07-18 16:02:39 +0530883 byte[] messageToWrite = getMessage(ddPacket);
884 ch.write(messageToWrite);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530885 }
886 } else if (state.getValue() >= OspfNeighborState.EXSTART.getValue()) {
887 if (!formAdjacencyOrNot()) {
888 state = OspfNeighborState.TWOWAY;
889 lsReqList.clear();
890 ddSummaryList.clear();
891 reTxList.clear();
892 }
893 }
894 }
895 }
896
897 /**
898 * LS Update Packet has been received while state was EXCHANGE or LOADING.
899 * Examine the received LSAs, check whether they were requested or not and process
900 * them accordingly. Therefore use method "processReceivedLsa" for further treatment.
901 *
902 * @param lsUpdPkt LS Update Packet received while Neighbor state was EXCHANGE or
903 * LOADING
904 * @param ch netty channel instance
905 * @throws Exception might throws exception
906 */
907 public void processLsUpdate(LsUpdate lsUpdPkt, Channel ch) throws Exception {
908 stopRxMtLsrTimer();
909 log.debug("OSPFNbr::processLsUpdate...!!!");
910
911 List lsaList = lsUpdPkt.getLsaList();
912 if (!lsaList.isEmpty()) {
913 Iterator itr = lsaList.iterator();
914
915 while (itr.hasNext()) {
916 LsaHeader lsaHeader = (LsaHeader) itr.next();
917 String key = ((OspfAreaImpl) ospfArea).getLsaKey(lsaHeader);
918
919 if (lsReqList.containsKey(key)) {
920 boolean removeIt;
921 removeIt = processReceivedLsa(lsaHeader, false, ch,
922 lsUpdPkt.sourceIp());
923 if (removeIt) {
924 lsReqList.remove(key);
925 }
926 } else {
927 // LSA was received via Flooding
928 processReceivedLsa(lsaHeader, true, ch,
929 lsUpdPkt.sourceIp());
930 }
931 }
932
933 if (lsReqList.isEmpty() && (state == OspfNeighborState.LOADING)) {
934 // loading complete
935 loadingDone();
936 } else {
937 stopRxMtLsrTimer();
938 LsRequest lsRequest = buildLsRequest();
939 lsRequest.setDestinationIp(lsUpdPkt.sourceIp());
940 setLastSentLsrPacket(lsRequest);
941
942 startRxMtLsrTimer(ch);
943 }
944 }
945 }
946
947 /***
948 * Method gets called when no more ls request list and moving to FULL State.
949 *
950 * @throws Exception might throws exception
951 */
952 public void loadingDone() throws Exception {
953 stopRxMtLsrTimer();
954 stopRxMtDdTimer();
955 log.debug("OSPFNbr::loadingDone...!!!");
956 state = OspfNeighborState.FULL;
957 ospfArea.refreshArea(ospfInterface);
958 }
959
960 /**
961 * Adds device and link.
962 *
963 * @param topologyForDeviceAndLink topology for device and link instance
964 */
965 private void callDeviceAndLinkAdding(TopologyForDeviceAndLink topologyForDeviceAndLink) {
966 Map<String, DeviceInformation> deviceInformationMap = topologyForDeviceAndLink.deviceInformationMap();
sunishvkf7c56552016-07-18 16:02:39 +0530967 Map<String, DeviceInformation> deviceInformationMapForPointToPoint =
968 topologyForDeviceAndLink.deviceInformationMapForPointToPoint();
969 Map<String, DeviceInformation> deviceInformationMapToDelete =
970 topologyForDeviceAndLink.deviceInformationMapToDelete();
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530971 Map<String, LinkInformation> linkInformationMap = topologyForDeviceAndLink.linkInformationMap();
sunishvkf7c56552016-07-18 16:02:39 +0530972 Map<String, LinkInformation> linkInformationMapForPointToPoint =
973 topologyForDeviceAndLink.linkInformationMapForPointToPoint();
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530974 OspfRouter ospfRouter = new OspfRouterImpl();
sunishvkf7c56552016-07-18 16:02:39 +0530975
976 if (deviceInformationMap.size() != 0) {
977 for (String key : deviceInformationMap.keySet()) {
978 DeviceInformation value = deviceInformationMap.get(key);
979 ospfRouter.setRouterIp(value.routerId());
980 ospfRouter.setAreaIdOfInterface(ospfArea.areaId());
981 ospfRouter.setNeighborRouterId(value.deviceId());
982 OspfDeviceTed ospfDeviceTed = new OspfDeviceTedImpl();
983 List<Ip4Address> ip4Addresses = value.interfaceId();
984 ospfDeviceTed.setIpv4RouterIds(ip4Addresses);
985 ospfRouter.setDeviceTed(ospfDeviceTed);
986 ospfRouter.setOpaque(ospfArea.isOpaqueEnabled());
987 if (value.isDr()) {
988 ospfRouter.setDr(value.isDr());
989 } else {
990 ospfRouter.setDr(false);
991 }
992 int size = value.interfaceId().size();
993 for (int i = 0; i < size; i++) {
994 ospfRouter.setInterfaceId(value.interfaceId().get(i));
995 }
996 ((OspfInterfaceImpl) ospfInterface).addDeviceInformation(ospfRouter);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530997 }
sunishvkf7c56552016-07-18 16:02:39 +0530998 }
999 if (deviceInformationMapForPointToPoint.size() != 0) {
1000 for (String key : deviceInformationMapForPointToPoint.keySet()) {
1001 DeviceInformation value = deviceInformationMapForPointToPoint.get(key);
1002 ospfRouter.setRouterIp(value.routerId());
1003 ospfRouter.setAreaIdOfInterface(ospfArea.areaId());
1004 ospfRouter.setNeighborRouterId(value.deviceId());
1005 OspfDeviceTed ospfDeviceTed = new OspfDeviceTedImpl();
1006 List<Ip4Address> ip4Addresses = value.interfaceId();
1007 ospfDeviceTed.setIpv4RouterIds(ip4Addresses);
1008 ospfRouter.setDeviceTed(ospfDeviceTed);
1009 ospfRouter.setOpaque(value.isDr());
1010 int size = value.interfaceId().size();
1011 for (int i = 0; i < size; i++) {
1012 ospfRouter.setInterfaceId(value.interfaceId().get(i));
1013 }
1014 ((OspfInterfaceImpl) ospfInterface).addDeviceInformation(ospfRouter);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301015 }
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301016 }
1017 for (Map.Entry<String, LinkInformation> entry : linkInformationMap.entrySet()) {
1018 String key = entry.getKey();
1019 LinkInformation value = entry.getValue();
1020 OspfRouter ospfRouterForLink = new OspfRouterImpl();
1021 ospfRouterForLink.setInterfaceId(value.interfaceIp());
1022 ospfRouterForLink.setAreaIdOfInterface(ospfArea.areaId());
1023 ospfRouterForLink.setOpaque(ospfArea.isOpaqueEnabled());
sunishvkf7c56552016-07-18 16:02:39 +05301024 OspfLinkTed ospfLinkTed = topologyForDeviceAndLink.getOspfLinkTedHashMap(
1025 value.linkDestinationId().toString());
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301026 if (ospfLinkTed == null) {
1027 ospfLinkTed = new OspfLinkTedImpl();
1028 ospfLinkTed.setMaximumLink(Bandwidth.bps(0));
1029 ospfLinkTed.setMaxReserved(Bandwidth.bps(0));
1030 ospfLinkTed.setTeMetric(0);
1031 }
1032
1033 if (!value.isLinkSrcIdNotRouterId()) {
1034 ospfRouterForLink.setRouterIp(value.linkSourceId());
1035 ospfRouterForLink.setNeighborRouterId(value.linkDestinationId());
1036 try {
sunishvkf7c56552016-07-18 16:02:39 +05301037 ((OspfInterfaceImpl) ospfInterface).addLinkInformation(ospfRouterForLink, ospfLinkTed);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301038 } catch (Exception e) {
sunishvkf7c56552016-07-18 16:02:39 +05301039 log.debug("Exception addLinkInformation: " + e.getMessage());
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301040 }
1041 }
1042 }
1043 }
1044
1045 // RFC 2328 Section 13 - partly as flooding procedure
1046
1047 /**
1048 * Processes the received Lsa.
1049 *
1050 * @param recLsa received Lsa
1051 * @param receivedViaFlooding received via flooding or not
1052 * @param ch channel instance
1053 * @param sourceIp source of this Lsa
1054 * @return true to remove it from lsReqList else false
1055 * @throws Exception might throws exception
1056 */
1057 public boolean processReceivedLsa(LsaHeader recLsa,
1058 boolean receivedViaFlooding, Channel ch, Ip4Address sourceIp)
1059 throws Exception {
Frank Wangd8ab0962017-08-11 11:09:30 +08001060 log.debug("OSPFNbr::processReceivedLsa(recLsa, receivedViaFlooding, ch)...!!!");
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301061
1062 //Validate the lsa checksum RFC 2328 13 (1)
1063 ChecksumCalculator checkSum = new ChecksumCalculator();
1064 if (!checkSum.isValidLsaCheckSum(recLsa,
1065 recLsa.getOspfLsaType().value(),
1066 OspfUtil.LSAPACKET_CHECKSUM_POS1,
1067 OspfUtil.LSAPACKET_CHECKSUM_POS2)) {
1068 log.debug("Checksum mismatch. Received LSA packet type {} ",
1069 recLsa.lsType());
1070
1071 return true;
1072 }
1073
1074 //If LSA type is unknown discard the lsa RFC 2328 13(2)
1075 if (((recLsa.getOspfLsaType().value() > OspfLsaType.EXTERNAL_LSA.value()) &&
1076 (recLsa.getOspfLsaType().value() < OspfLsaType.LINK_LOCAL_OPAQUE_LSA.value())) ||
1077 (recLsa.getOspfLsaType().value() > OspfLsaType.AS_OPAQUE_LSA.value())) {
1078 return true;
1079 }
1080
1081 //If LSA type is external & the area is configured as stub area discard the lsa RFC 2328 13(3)
1082 if ((recLsa.getOspfLsaType() == OspfLsaType.EXTERNAL_LSA) &&
sunish vkaa48da82016-03-02 23:17:06 +05301083 (!ospfArea.isExternalRoutingCapability())) {
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301084 return true;
1085 }
1086
1087 //if lsa age is equal to maxage && instance is not in lsdb && none of neighbors are in exchange
1088 // or loading state
1089 // Acknowledge the receipt by sending LSAck to the sender. 2328 13(4)
1090 if ((recLsa.age() == OspfParameters.MAXAGE) &&
1091 (ospfArea.lsaLookup(recLsa) == null) &&
1092 ospfArea.noNeighborInLsaExchangeProcess()) {
1093 // RFC 2328 Section 13. (4)
1094 // Because the LSA was not yet requested, it is treated as a flooded LSA and thus
1095 // acknowledged.
1096 directAcknowledge(recLsa, ch, sourceIp);
1097 return true;
1098 }
1099
1100 String key = ((OspfAreaImpl) ospfArea).getLsaKey(recLsa);
1101 LsaWrapper lsWrapper = ospfArea.lsaLookup(recLsa);
1102 String status = isNullorLatest(lsWrapper, recLsa);
1103 //Section 13 (5)
1104 if (status.equals("isNullorLatest")) {
1105
1106 if (recLsa.lsType() == OspfLsaType.ROUTER.value() && recLsa.advertisingRouter().equals(
1107 ospfArea.routerId())) {
1108 if (recLsa.lsSequenceNo() > ((LsaWrapperImpl) lsWrapper).lsaHeader().lsSequenceNo()) {
1109 ospfArea.setDbRouterSequenceNumber(recLsa.lsSequenceNo() + 1);
1110 processSelfOriginatedLsa();
1111 }
1112
1113 if (recLsa.age() == OspfParameters.MAXAGE) {
1114 ((LsaWrapperImpl) lsWrapper).lsaHeader().setAge(OspfParameters.MAXAGE);
1115 //remove from db & bin, add the lsa to MaxAge bin.
1116 ospfArea.addLsaToMaxAgeBin(((OspfAreaImpl) ospfArea).getLsaKey(((LsaWrapperImpl)
1117 lsWrapper).lsaHeader()), lsWrapper);
1118 ospfArea.removeLsaFromBin(lsWrapper);
1119 }
1120
1121 return true;
1122 } else if (recLsa.lsType() == OspfLsaType.NETWORK.value() && isLinkStateMatchesOwnRouterId(
1123 recLsa.linkStateId())) {
1124 // if we are not DR or if origination router ID not equal to our router ID //either
1125 // DR state changed or our router ID was changed
1126 //set LSAge = MaxAge
1127 //flood the LSA
1128 if (((OspfInterfaceImpl) ospfInterface).state() != OspfInterfaceState.DR ||
1129 !recLsa.advertisingRouter().equals(
1130 ospfArea.routerId())) {
1131 if (lsWrapper != null) {
1132 ((LsaWrapperImpl) lsWrapper).lsaHeader().setAge(OspfParameters.MAXAGE);
1133 //remove from bin, add the lsa to MaxAge bin.
1134 ospfArea.addLsaToMaxAgeBin(((OspfAreaImpl) ospfArea).getLsaKey(((LsaWrapperImpl)
1135 lsWrapper).lsaHeader()), lsWrapper);
1136 ospfArea.removeLsaFromBin(lsWrapper);
1137 } else {
1138 recLsa.setAge(OspfParameters.MAXAGE);
1139 ((OspfAreaImpl) ospfArea).addToOtherNeighborLsaTxList(recLsa);
1140 }
1141 }
1142
1143 return true;
1144 } else {
1145 if (recLsa.age() == OspfParameters.MAXAGE) {
1146 ((OspfInterfaceImpl) ospfInterface).addLsaHeaderForDelayAck(recLsa);
1147 //remove from db & bin, add the lsa to MaxAge bin.
1148 if (lsWrapper != null) {
1149 lsWrapper.setLsaAgeReceived(OspfParameters.MAXAGE);
1150 ospfArea.addLsaToMaxAgeBin(((OspfAreaImpl) ospfArea).getLsaKey(((LsaWrapperImpl)
1151 lsWrapper).lsaHeader()), lsWrapper);
1152 ospfArea.removeLsaFromBin(lsWrapper);
1153 } else {
1154 ((OspfAreaImpl) ospfArea).addToOtherNeighborLsaTxList(recLsa);
1155 }
1156
1157 return true;
1158 } else {
1159 ospfArea.addLsa(recLsa, ospfInterface);
1160 log.debug("Inside addLsaMethod");
1161 topologyForDeviceAndLink.addLocalDevice(recLsa, ospfInterface, ospfArea);
1162 callDeviceAndLinkAdding(topologyForDeviceAndLink);
1163 log.debug("Adding to lsdb interface State {}", ((OspfInterfaceImpl) ospfInterface).state().value());
1164 // should not send any acknowledge if flooded out on receiving interface
1165 if (((OspfInterfaceImpl) ospfInterface).state().value() == OspfInterfaceState.BDR.value()) {
1166 if (neighborDr.equals(sourceIp)) {
1167 log.debug("Adding for delayed ack {}", recLsa);
1168 ((OspfInterfaceImpl) ospfInterface).addLsaHeaderForDelayAck(recLsa);
1169 }
1170 } else {
1171 log.debug("Adding for delayed ack {}", recLsa);
1172 ((OspfInterfaceImpl) ospfInterface).addLsaHeaderForDelayAck(recLsa);
1173 }
1174
1175 if (((OspfInterfaceImpl) ospfInterface).state().value() == OspfInterfaceState.DR.value() ||
1176 ((OspfInterfaceImpl) ospfInterface).state().value() ==
1177 OspfInterfaceState.POINT2POINT.value()) {
1178 ((OspfAreaImpl) ospfArea).addToOtherNeighborLsaTxList(recLsa);
1179 }
1180 }
1181
1182 }
1183 }
1184 // RFC 2328 Section 13 (6)
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001185 if (lsReqList.containsValue(key)) {
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301186 badLSReq(ch);
1187 }
1188 if (status.equals("same")) { //13 (7)
1189 if (pendingReTxList.containsKey(key)) {
1190 pendingReTxList.remove(key);
1191 if (((OspfInterfaceImpl) ospfInterface).state().value() == OspfInterfaceState.BDR.value()) {
1192 if (neighborDr.equals(recLsa.advertisingRouter())) {
1193 ((OspfInterfaceImpl) ospfInterface).addLsaHeaderForDelayAck(recLsa);
1194 }
1195 }
1196 } else {
1197 directAcknowledge(recLsa, ch, sourceIp);
1198 return true;
1199 }
1200 } else if (status.equals("old")) { // section 13 - point 8
1201 if ((recLsa.lsSequenceNo() == OspfParameters.MAXSEQUENCENUMBER) &&
1202 (recLsa.age() == OspfParameters.MAXAGE)) {
1203 // section 13 - point 8
1204 // simple discard the received LSA -
1205 return true;
1206 } else {
1207 // respond back with the same LSA
1208 //Using flood LSA to sent the LSUpdate back to advertising router
1209 int diff = Math.abs(lsWrapper.lsaAgeReceived() - recLsa.age());
1210 if (diff > OspfParameters.MINLSARRIVAL) {
1211 sendLsa(((LsaWrapperImpl) lsWrapper).lsaHeader(), sourceIp, ch);
1212 }
1213 }
1214 }
sunishvkf7c56552016-07-18 16:02:39 +05301215
1216 constructDeviceInformationFromDb();
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301217 callDeviceAndLinkAdding(topologyForDeviceAndLink);
sunishvkf7c56552016-07-18 16:02:39 +05301218
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301219 return true;
1220 }
1221
1222 /**
sunishvkf7c56552016-07-18 16:02:39 +05301223 * Constructs device and link information from link state database.
1224 */
1225 private void constructDeviceInformationFromDb() {
1226 OspfLsdb database = ospfArea.database();
1227 List lsas = database.getAllLsaHeaders(true, true);
1228 Iterator iterator = lsas.iterator();
1229 while (iterator.hasNext()) {
1230 OspfLsa ospfLsa = (OspfLsa) iterator.next();
1231 if (ospfLsa.getOspfLsaType().value() == OspfLsaType.ROUTER.value()) {
1232 topologyForDeviceAndLink.addLocalDevice(ospfLsa, ospfInterface, ospfArea);
1233 } else if (ospfLsa.getOspfLsaType().value() == OspfLsaType.NETWORK.value()) {
1234 topologyForDeviceAndLink.addLocalDevice(ospfLsa, ospfInterface, ospfArea);
1235 }
1236 }
1237 }
1238
1239 /**
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301240 * Checks Link State ID is equal to one of the router's own IP interface addresses.
1241 *
1242 * @param linkStateId link state id
1243 * @return true if link state matches or false
1244 */
1245 private boolean isLinkStateMatchesOwnRouterId(String linkStateId) {
1246 boolean isLinkStateMatches = false;
sunishvkf7c56552016-07-18 16:02:39 +05301247 List<OspfInterface> interfaceLst = ospfArea.ospfInterfaceList();
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301248 for (OspfInterface ospfInterface : interfaceLst) {
1249 if (ospfInterface.ipAddress().toString().equals(linkStateId)) {
1250 isLinkStateMatches = true;
1251 break;
1252 }
1253 }
1254
1255 return isLinkStateMatches;
1256 }
1257
1258 /**
1259 * RFC 2328 Section 13 (5).
1260 *
1261 * @param lsWrapper ls wrapper instance
1262 * @param recLsa received LSA instance
1263 * @return returns a string status
1264 */
1265 public String isNullorLatest(LsaWrapper lsWrapper, LsaHeader recLsa) {
1266
1267
1268 if (lsWrapper != null) {
1269 LsaHeader ownLsa = (LsaHeader) lsWrapper.ospfLsa();
1270 String status = ospfArea.isNewerOrSameLsa(recLsa, ownLsa);
1271
1272 if (status.equals("latest")) {
1273 return "isNullorLatest";
1274 } else {
1275 return status;
1276 }
1277 } else {
1278 return "isNullorLatest";
1279 }
1280 }
1281
1282 /**
1283 * RFC 2328 section 13.4
1284 * Processing self-originated LSAs.
1285 *
1286 * @throws Exception might throws exception
1287 */
1288 public void processSelfOriginatedLsa() throws Exception {
1289 ospfArea.refreshArea(ospfInterface);
1290 }
1291
1292 /**
1293 * Sends the LSA to destination address.
1294 *
1295 * @param lsa LSA instance to sent
1296 * @param destination destination IP address
1297 * @param ch netty channel instance
1298 */
1299 public void sendLsa(LsaHeader lsa, Ip4Address destination, Channel ch) {
1300 if (lsa == null) {
1301 return;
1302 }
1303
1304 LsUpdate responseLsUpdate = new LsUpdate();
1305 // seting OSPF Header
1306 responseLsUpdate.setOspfVer(OspfUtil.OSPF_VERSION);
1307 responseLsUpdate.setOspftype(OspfPacketType.LSUPDATE.value());
1308 responseLsUpdate.setRouterId(ospfArea.routerId());
1309 responseLsUpdate.setAreaId(ospfArea.areaId());
1310 responseLsUpdate.setAuthType(OspfUtil.NOT_ASSIGNED);
1311 responseLsUpdate.setAuthentication(OspfUtil.NOT_ASSIGNED);
1312 responseLsUpdate.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
1313 responseLsUpdate.setChecksum(OspfUtil.NOT_ASSIGNED);
1314 responseLsUpdate.setNumberOfLsa(1);
1315 responseLsUpdate.addLsa(lsa);
1316
1317 //setting the destination.
1318 responseLsUpdate.setDestinationIp(destination);
sunishvkf7c56552016-07-18 16:02:39 +05301319 byte[] messageToWrite = getMessage(responseLsUpdate);
1320 ch.write(messageToWrite);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301321 }
1322
1323 /**
1324 * Sends a direct Acknowledgment for a particular LSA to the Neighbor.
1325 *
1326 * @param ackLsa LSA instance
1327 * @param ch netty channel instance
1328 * @param sourceIp source IP address
1329 */
1330 public void directAcknowledge(LsaHeader ackLsa, Channel ch, Ip4Address sourceIp) {
1331 log.debug("OSPFNbr::directAcknowledge...!!!");
1332
1333 LsAcknowledge ackContent = new LsAcknowledge();
1334 // seting OSPF Header
1335 ackContent.setOspfVer(OspfUtil.OSPF_VERSION);
1336 ackContent.setOspftype(OspfPacketType.LSAACK.value());
1337 ackContent.setRouterId(ospfArea.routerId());
1338 ackContent.setAreaId(ospfArea.areaId());
1339 ackContent.setAuthType(OspfUtil.NOT_ASSIGNED);
1340 ackContent.setAuthentication(OspfUtil.NOT_ASSIGNED);
1341 ackContent.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
1342 ackContent.setChecksum(OspfUtil.NOT_ASSIGNED);
1343 ackContent.addLinkStateHeader(ackLsa);
1344 //setting the destination IP
1345 ackContent.setDestinationIp(sourceIp);
sunishvkf7c56552016-07-18 16:02:39 +05301346 byte[] messageToWrite = getMessage(ackContent);
1347 ch.write(messageToWrite);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301348 }
1349
1350 /**
1351 * Called when neighbor is down.
1352 *
1353 * @throws Exception might throws exception
1354 */
1355 public void neighborDown() throws Exception {
1356 log.debug("Neighbor Down {} and NeighborId {}", neighborIpAddr,
1357 neighborId);
1358 stopInactivityTimeCheck();
1359 stopRxMtDdTimer();
1360 stopRxMtLsrTimer();
1361
1362 if (floodingTimerScheduled) {
1363 stopFloodingTimer();
1364 floodingTimerScheduled = false;
1365 }
1366
1367 state = OspfNeighborState.DOWN;
1368 ospfArea.refreshArea(ospfInterface);
1369 lsReqList.clear();
1370 ddSummaryList.clear();
1371 if (neighborIpAddr.equals(neighborBdr) ||
1372 neighborIpAddr.equals(neighborDr)) {
sunishvkf7c56552016-07-18 16:02:39 +05301373 ((OspfInterfaceImpl) ospfInterface).neighborChange();
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301374 }
1375 log.debug("Neighbor Went Down : "
1376 + this.neighborIpAddr + " , " + this.neighborId);
1377 removeDeviceDetails(this.neighborId);
1378 OspfRouter ospfRouter = new OspfRouterImpl();
1379 ospfRouter.setRouterIp(this.neighborId());
1380 ospfRouter.setInterfaceId(ospfInterface.ipAddress());
1381 ospfRouter.setAreaIdOfInterface(ospfArea.areaId());
1382 ospfRouter.setDeviceTed(new OspfDeviceTedImpl());
sunishvkf7c56552016-07-18 16:02:39 +05301383 ((OspfInterfaceImpl) ospfInterface).removeDeviceInformation(ospfRouter);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301384 removeDeviceDetails(this.neighborIpAddr);
1385 OspfRouter ospfRouter1 = new OspfRouterImpl();
1386 ospfRouter1.setRouterIp(this.neighborIpAddr);
1387 ospfRouter1.setInterfaceId(ospfInterface.ipAddress());
1388 ospfRouter1.setAreaIdOfInterface(ospfArea.areaId());
1389 ospfRouter1.setDeviceTed(new OspfDeviceTedImpl());
sunishvkf7c56552016-07-18 16:02:39 +05301390 ((OspfInterfaceImpl) ospfInterface).removeDeviceInformation(ospfRouter1);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301391 }
1392
1393 /**
1394 * Removes device details.
1395 *
1396 * @param routerId router id
1397 */
1398 private void removeDeviceDetails(Ip4Address routerId) {
1399 String key = "device:" + routerId;
1400 topologyForDeviceAndLink.removeDeviceInformationMap(key);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301401 }
1402
1403 /**
1404 * Starts the inactivity timer.
1405 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001406 @Override
sunishvkf7c56552016-07-18 16:02:39 +05301407 public void startInactivityTimeCheck() {
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301408 if (!inActivityTimerScheduled) {
1409 log.debug("OSPFNbr::startInactivityTimeCheck");
1410 inActivityTimeCheckTask = new InternalInactivityTimeCheck();
1411 exServiceInActivity = Executors.newSingleThreadScheduledExecutor();
1412 exServiceInActivity.scheduleAtFixedRate(inActivityTimeCheckTask, routerDeadInterval,
1413 routerDeadInterval, TimeUnit.SECONDS);
1414 inActivityTimerScheduled = true;
1415 }
1416 }
1417
1418 /**
1419 * Stops the inactivity timer.
1420 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001421 @Override
sunishvkf7c56552016-07-18 16:02:39 +05301422 public void stopInactivityTimeCheck() {
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301423 if (inActivityTimerScheduled) {
1424 log.debug("OSPFNbr::stopInactivityTimeCheck ");
1425 exServiceInActivity.shutdown();
1426 inActivityTimerScheduled = false;
1427 }
1428 }
1429
1430 /**
1431 * Starts the flooding timer.
1432 *
1433 * @param channel channel instance
1434 */
1435 public void startFloodingTimer(Channel channel) {
1436
1437 if (!floodingTimerScheduled) {
1438 log.debug("OSPFNbr::startFloodingTimer");
1439 floodingTask = new InternalFloodingTask(channel);
1440 exServiceFlooding = Executors.newSingleThreadScheduledExecutor();
1441 //Run every 5 seconds.
1442 exServiceFlooding.scheduleAtFixedRate(floodingTask, OspfParameters.START_NOW,
1443 OspfParameters.MINLSINTERVAL, TimeUnit.SECONDS);
1444 floodingTimerScheduled = true;
1445 }
1446 }
1447
1448 /**
1449 * Stops the flooding timer.
1450 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001451 @Override
sunishvkf7c56552016-07-18 16:02:39 +05301452 public void stopFloodingTimer() {
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301453 if (floodingTimerScheduled) {
1454 log.debug("OSPFNbr::stopFloodingTimer ");
1455 exServiceFlooding.shutdown();
1456 floodingTimerScheduled = false;
1457 }
1458 }
1459
1460 /**
1461 * Starts the Dd Retransmission executor task.
1462 *
1463 * @param ch netty channel instance
1464 */
1465 private void startRxMtDdTimer(Channel ch) {
1466 if (!rxmtDdPacketTimerScheduled) {
1467 long retransmitInterval = ospfInterface.reTransmitInterval();
1468 rxmtDdPacketTask = new InternalRxmtDdPacket(ch);
1469 exServiceRxmtDDPacket = Executors.newSingleThreadScheduledExecutor();
1470 exServiceRxmtDDPacket.scheduleAtFixedRate(rxmtDdPacketTask, retransmitInterval,
1471 retransmitInterval, TimeUnit.SECONDS);
1472 rxmtDdPacketTimerScheduled = true;
1473 }
1474 }
1475
1476 /**
1477 * Stops the Dd Retransmission executor task.
1478 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001479 @Override
sunishvkf7c56552016-07-18 16:02:39 +05301480 public void stopRxMtDdTimer() {
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301481 if (rxmtDdPacketTimerScheduled) {
1482 exServiceRxmtDDPacket.shutdown();
1483 rxmtDdPacketTimerScheduled = false;
1484 }
1485 }
1486
1487 /**
1488 * Starts Ls request retransmission executor task.
1489 *
1490 * @param ch Netty channel instance
1491 */
1492 private void startRxMtLsrTimer(Channel ch) {
1493 if (!rxmtLsrTimerScheduled) {
1494 log.debug("OSPFNbr::startRxMtLsrTimer...!!!");
1495 long retransmitIntrvl = ospfInterface.reTransmitInterval();
1496 rxmtLsrPacketTask = new InternalRxmtLsrPacket(ch);
1497 exServiceRxmtLsr = Executors.newSingleThreadScheduledExecutor();
1498 exServiceRxmtLsr.scheduleAtFixedRate(rxmtLsrPacketTask, retransmitIntrvl,
1499 retransmitIntrvl, TimeUnit.SECONDS);
1500 rxmtLsrTimerScheduled = true;
1501 }
1502 }
1503
1504 /**
1505 * Stops Ls request retransmission executor task.
1506 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001507 @Override
sunishvkf7c56552016-07-18 16:02:39 +05301508 public void stopRxMtLsrTimer() {
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301509 if (rxmtLsrTimerScheduled) {
1510 exServiceRxmtLsr.shutdown();
1511 rxmtLsrTimerScheduled = false;
1512 }
1513 }
1514
1515 /**
1516 * Gets the last sent DdPacket.
1517 *
1518 * @return DdPacket instance
1519 */
1520 public DdPacket lastDdPacket() {
1521 return lastDdPacket;
1522 }
1523
1524 /**
1525 * Sets the last sent DdPacket.
1526 *
1527 * @param lastDdPacket DdPacket instance
1528 */
1529 public void setLastDdPacket(DdPacket lastDdPacket) {
1530 this.lastDdPacket = lastDdPacket;
1531 }
1532
1533 /**
1534 * Gets neighbor id.
1535 *
1536 * @return neighbor id
1537 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001538 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301539 public Ip4Address neighborId() {
1540 return neighborId;
1541 }
1542
1543 /**
1544 * Sets the neighbor id.
1545 *
1546 * @param neighborId neighbor id
1547 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001548 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301549 public void setNeighborId(Ip4Address neighborId) {
1550 this.neighborId = neighborId;
1551 }
1552
1553 /**
1554 * Gets the neighbor DR address.
1555 *
1556 * @return neighbor DR address
1557 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001558 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301559 public Ip4Address neighborDr() {
1560 return neighborDr;
1561 }
1562
1563 /**
1564 * Sets the neighbor DR address.
1565 *
1566 * @param neighborDr neighbor DR address
1567 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001568 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301569 public void setNeighborDr(Ip4Address neighborDr) {
1570 this.neighborDr = neighborDr;
1571 }
1572
1573 /**
1574 * Gets the neighbor BDR address.
1575 *
1576 * @return neighbor BDR address
1577 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001578 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301579 public Ip4Address neighborBdr() {
1580 return neighborBdr;
1581 }
1582
1583 /**
1584 * Sets the neighbor BDR address.
1585 *
1586 * @param neighborBdr neighbor BDR address
1587 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001588 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301589 public void setNeighborBdr(Ip4Address neighborBdr) {
1590 this.neighborBdr = neighborBdr;
1591 }
1592
1593 /**
1594 * Gets router priority.
1595 *
1596 * @return router priority
1597 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001598 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301599 public int routerPriority() {
1600 return routerPriority;
1601 }
1602
1603 /**
1604 * Sets router priority.
1605 *
1606 * @param routerPriority router priority
1607 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001608 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301609 public void setRouterPriority(int routerPriority) {
1610 this.routerPriority = routerPriority;
1611 }
1612
1613 /**
1614 * Gets the options value.
1615 *
1616 * @return options value
1617 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001618 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301619 public int options() {
1620 return options;
1621 }
1622
1623 /**
1624 * Sets the options value.
1625 *
1626 * @param options options value
1627 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001628 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301629 public void setOptions(int options) {
1630 this.options = options;
1631 }
1632
1633 /**
1634 * Gets the DD sequence number.
1635 *
1636 * @return DD sequence number
1637 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001638 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301639 public long ddSeqNum() {
1640 return ddSeqNum;
1641 }
1642
1643 /**
1644 * Sets the DD sequence number.
1645 *
1646 * @param ddSeqNum DD sequence number
1647 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001648 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301649 public void setDdSeqNum(long ddSeqNum) {
1650 this.ddSeqNum = ddSeqNum;
1651 }
1652
1653 /**
1654 * Gets neighbor is master or not.
1655 *
1656 * @return true if neighbor is master else false
1657 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001658 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301659 public int isMaster() {
1660 return isMaster;
1661 }
1662
1663 /**
1664 * Gets the last sent DD Packet.
1665 *
1666 * @return last sent DD Packet
1667 */
1668 public DdPacket lastSentDdPacket() {
1669 return lastSentDdPacket;
1670 }
1671
1672 /**
1673 * Sets the last sent DD Packet.
1674 *
1675 * @param lastSentDdPacket last sent DD Packet
1676 */
1677 public void setLastSentDdPacket(DdPacket lastSentDdPacket) {
1678 this.lastSentDdPacket = lastSentDdPacket;
1679 }
1680
1681 /**
1682 * Gets the last sent Ls Request Packet.
1683 *
1684 * @return last sent Ls Request Packet
1685 */
1686 public LsRequest getLastSentLsrPacket() {
1687 return lastSentLsrPacket;
1688 }
1689
1690 /**
1691 * Sets the last sent Ls Request Packet.
1692 *
1693 * @param lastSentLsrPacket last sent Ls Request Packet
1694 */
1695 public void setLastSentLsrPacket(LsRequest lastSentLsrPacket) {
1696 this.lastSentLsrPacket = lastSentLsrPacket;
1697 }
1698
1699 /**
1700 * Gets the neighbors state.
1701 *
1702 * @return neighbors state
1703 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001704 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301705 public OspfNeighborState getState() {
1706 return state;
1707 }
1708
1709 /**
1710 * Sets the neighbors state.
1711 *
1712 * @param state neighbors state
1713 */
1714 public void setState(OspfNeighborState state) {
1715 this.state = state;
1716 }
1717
1718 /**
1719 * Sets neighbor is master or not.
1720 *
1721 * @param isMaster neighbor is master or not
1722 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001723 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301724 public void setIsMaster(int isMaster) {
1725 this.isMaster = isMaster;
1726 }
1727
1728 /**
1729 * Gets the ls request list.
1730 *
1731 * @return ls request list
1732 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001733 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301734 public Hashtable getLsReqList() {
1735 return lsReqList;
1736 }
1737
1738 /**
1739 * Gets the reTxList instance.
1740 *
1741 * @return reTxList instance
1742 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001743 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301744 public Map getReTxList() {
1745 return reTxList;
1746 }
1747
1748 /**
1749 * Gets the pending re transmit list.
1750 *
1751 * @return pendingReTxList instance
1752 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001753 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301754 public Map<String, OspfLsa> getPendingReTxList() {
1755 return pendingReTxList;
1756 }
1757
sunishvkf7c56552016-07-18 16:02:39 +05301758 /**
1759 * Gets message as bytes.
1760 *
1761 * @param ospfMessage OSPF message
1762 * @return OSPF message
1763 */
1764 private byte[] getMessage(OspfMessage ospfMessage) {
1765 OspfMessageWriter messageWriter = new OspfMessageWriter();
1766 if (((OspfInterfaceImpl) ospfInterface).state().equals(OspfInterfaceState.POINT2POINT)) {
1767 ospfMessage.setDestinationIp(OspfUtil.ALL_SPF_ROUTERS);
1768 }
1769 return (messageWriter.getMessage(ospfMessage, ospfInterface.interfaceIndex(),
1770 ((OspfInterfaceImpl) ospfInterface).state().value()));
1771 }
1772
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301773
1774 /**
1775 * Represents a Task which will do an inactivity time check.
1776 */
1777 private class InternalInactivityTimeCheck implements Runnable {
1778 /**
1779 * Constructor.
1780 */
1781 InternalInactivityTimeCheck() {
1782 }
1783
1784 @Override
1785 public void run() {
1786 try {
1787 log.debug("Neighbor Not Heard till the past router dead interval .");
1788 neighborDown();
1789 } catch (Exception e) {
1790 log.debug("Exception at inactivity time check...!!!");
1791 }
1792 }
1793 }
1794
1795 /**
1796 * Task which re transmits DdPacket every configured time interval.
1797 */
1798 private class InternalRxmtDdPacket implements Runnable {
1799 Channel ch;
1800
1801 /**
1802 * Creates an instance or Re transmit DD packet timer.
1803 *
1804 * @param ch netty channel instance
1805 */
1806 InternalRxmtDdPacket(Channel ch) {
1807 this.ch = ch;
1808 }
1809
1810 @Override
1811 public void run() {
1812 if ((ch != null) && ch.isConnected()) {
1813 DdPacket ddPacket = lastSentDdPacket();
sunishvkf7c56552016-07-18 16:02:39 +05301814 byte[] messageToWrite = getMessage(ddPacket);
1815 ch.write(messageToWrite);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301816 log.debug("Re-Transmit DD Packet .");
1817 } else {
1818 log.debug(
1819 "Re-Transmit DD Packet failed. Channel not connected..");
1820 }
1821 }
1822 }
1823
1824 /**
1825 * Task which re transmits Ls request Packet every configured time interval.
1826 */
1827 private class InternalRxmtLsrPacket implements Runnable {
1828 Channel ch;
1829
1830 /**
1831 * Creates an instance or Re transmit LS Request packet timer.
1832 *
1833 * @param ch netty channel instance
1834 */
1835 InternalRxmtLsrPacket(Channel ch) {
1836 this.ch = ch;
1837 }
1838
1839 @Override
1840 public void run() {
1841 if ((ch != null) && ch.isConnected()) {
1842 LsRequest lsrPacket = getLastSentLsrPacket();
sunishvkf7c56552016-07-18 16:02:39 +05301843 byte[] messageToWrite = getMessage(lsrPacket);
1844 ch.write(messageToWrite);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301845 log.debug("Re-Transmit LSRequest Packet .");
1846 } else {
1847 log.debug(
1848 "Re-Transmit LSRequest failed. Channel not connected..");
1849 }
1850 }
1851 }
1852
1853 /**
1854 * Task which transmits Ls update Packet based on the re transmit list.
1855 * every configured time interval.
1856 */
1857 private class InternalFloodingTask implements Runnable {
1858 Channel channel;
1859
1860 /**
1861 * Creates an instance or Flooding task.
1862 *
1863 * @param ch netty channel instance
1864 */
1865 InternalFloodingTask(Channel ch) {
1866 this.channel = ch;
1867 }
1868
1869 @Override
1870 public void run() {
1871 if ((channel != null) && channel.isConnected()) {
1872
1873 if ((pendingReTxList != null) && (pendingReTxList.size() > 0)) {
1874 List<LsUpdate> lsUpdateList = buildLsUpdate(pendingReTxList);
1875
1876 for (LsUpdate lsupdate : lsUpdateList) {
1877 //Pending for acknowledge directly sent it to neighbor
1878 lsupdate.setDestinationIp(neighborIpAddr);
sunishvkf7c56552016-07-18 16:02:39 +05301879 byte[] messageToWrite = getMessage(lsupdate);
1880 channel.write(messageToWrite);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301881 }
1882 }
1883
1884 if ((reTxList != null) && (reTxList.size() > 0)) {
1885 List<LsUpdate> lsUpdateList = buildLsUpdate(reTxList);
1886
1887 for (LsUpdate lsupdate : lsUpdateList) {
1888 //set the destination
1889 if ((((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.DR) ||
1890 (((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.POINT2POINT)) {
1891 lsupdate.setDestinationIp(OspfUtil.ALL_SPF_ROUTERS);
1892 } else if (((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.DROTHER ||
1893 (((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.BDR)) {
1894 lsupdate.setDestinationIp(neighborDr);
1895 }
sunishvkf7c56552016-07-18 16:02:39 +05301896 byte[] messageToWrite = getMessage(lsupdate);
1897 channel.write(messageToWrite);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301898 }
1899 }
1900 }
1901 }
1902
1903 /**
1904 * Builds the LsUpdate for flooding.
1905 *
1906 * @param txList list contains LSAs
1907 * @return list of LsUpdate instances
1908 */
1909 private List buildLsUpdate(Map<String, OspfLsa> txList) {
1910 List<LsUpdate> lsUpdateList = new ArrayList<>();
1911 ListIterator itr = new ArrayList(txList.keySet()).listIterator();
1912 while (itr.hasNext()) {
1913 LsUpdate lsupdate = new LsUpdate();
1914 // seting OSPF Header
1915 lsupdate.setOspfVer(OspfUtil.OSPF_VERSION);
1916 lsupdate.setOspftype(OspfPacketType.LSUPDATE.value());
1917 lsupdate.setRouterId(ospfArea.routerId());
1918 lsupdate.setAreaId(ospfArea.areaId());
1919 lsupdate.setAuthType(OspfUtil.NOT_ASSIGNED);
1920 lsupdate.setAuthentication(OspfUtil.NOT_ASSIGNED);
1921 lsupdate.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
1922 lsupdate.setChecksum(OspfUtil.NOT_ASSIGNED);
1923
1924 //limit to mtu
1925 int currentLength = OspfUtil.OSPF_HEADER_LENGTH + OspfUtil.FOUR_BYTES;
1926 int maxSize = ospfInterface.mtu() -
1927 OspfUtil.LSA_HEADER_LENGTH; // subtract a normal IP header.
1928
1929 int noLsa = 0;
1930 while (itr.hasNext()) {
1931
1932 String key = (String) itr.next();
1933 OspfLsa lsa = txList.get(key);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301934 if (lsa != null) {
Palash Kala9bf01a12017-03-30 14:08:55 +09001935 if ((lsa.age() + OspfParameters.INFTRA_NS_DELAY) >= OspfParameters.MAXAGE) {
1936 ((LsaHeader) lsa.lsaHeader()).setAge(OspfParameters.MAXAGE);
1937 } else {
1938 ((LsaHeader) lsa.lsaHeader()).setAge(lsa.age() + OspfParameters.INFTRA_NS_DELAY);
1939 }
1940
1941 if ((currentLength + ((LsaHeader) lsa.lsaHeader()).lsPacketLen()) >= maxSize) {
1942 itr.previous();
1943 break;
1944 }
1945 log.debug("FloodingTimer::LSA Type::{}, Header: {}, LSA: {}", lsa.getOspfLsaType(),
1946 lsa.lsaHeader(), lsa);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301947 lsupdate.addLsa(lsa);
1948 noLsa++;
1949 currentLength = currentLength + ((LsaHeader) lsa.lsaHeader()).lsPacketLen();
1950 }
1951 log.debug("FloodingTimer::Removing key {}", key);
1952 if (txList.equals(reTxList)) {
1953 reTxList.remove(key);
1954 pendingReTxList.put(key, lsa);
1955 }
1956 }
1957 //set number of lsa's
1958 lsupdate.setNumberOfLsa(noLsa);
1959 lsUpdateList.add(lsupdate);
1960 }
1961 return lsUpdateList;
1962 }
1963 }
Ray Milkey0bb1e102016-11-10 14:51:27 -08001964}