blob: 0f7a91c4770aa504ad94306b1d78486c3195732b [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;
Ray Milkey019fba42018-01-31 14:07:47 -080041import org.onosproject.ospf.exceptions.OspfParseException;
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +053042import org.onosproject.ospf.protocol.lsa.LsaHeader;
43import org.onosproject.ospf.protocol.lsa.OpaqueLsaHeader;
44import org.onosproject.ospf.protocol.lsa.types.OpaqueLsa10;
45import org.onosproject.ospf.protocol.lsa.types.TopLevelTlv;
sunishvkf7c56552016-07-18 16:02:39 +053046import org.onosproject.ospf.protocol.ospfpacket.OspfMessageWriter;
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +053047import org.onosproject.ospf.protocol.ospfpacket.OspfPacketHeader;
48import org.onosproject.ospf.protocol.ospfpacket.subtype.LsRequestPacket;
49import org.onosproject.ospf.protocol.ospfpacket.types.DdPacket;
50import org.onosproject.ospf.protocol.ospfpacket.types.LsAcknowledge;
51import org.onosproject.ospf.protocol.ospfpacket.types.LsRequest;
52import org.onosproject.ospf.protocol.ospfpacket.types.LsUpdate;
53import org.onosproject.ospf.protocol.util.ChecksumCalculator;
54import org.onosproject.ospf.protocol.util.OspfInterfaceState;
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +053055import org.onosproject.ospf.protocol.util.OspfParameters;
56import org.onosproject.ospf.protocol.util.OspfUtil;
57import org.slf4j.Logger;
58import org.slf4j.LoggerFactory;
59
60import java.util.ArrayList;
61import java.util.HashMap;
62import java.util.Hashtable;
63import java.util.Iterator;
64import java.util.LinkedHashMap;
65import java.util.List;
66import java.util.ListIterator;
67import java.util.Map;
68import java.util.Set;
69import java.util.concurrent.CopyOnWriteArrayList;
70import java.util.concurrent.Executors;
71import java.util.concurrent.ScheduledExecutorService;
72import java.util.concurrent.TimeUnit;
73
74/**
75 * Represents an OSPF neighbor.
76 * The first thing an OSPF router must do is find its neighbors and form adjacency.
77 * Each neighbor that the router finds will be represented by this class.
78 */
79public class OspfNbrImpl implements OspfNbr {
80 private static final Logger log = LoggerFactory.getLogger(OspfNbrImpl.class);
81 private OspfNeighborState state;
82 private InternalRxmtDdPacket rxmtDdPacketTask;
83 private InternalInactivityTimeCheck inActivityTimeCheckTask;
84 private InternalFloodingTask floodingTask;
85 private InternalRxmtLsrPacket rxmtLsrPacketTask;
86 private ScheduledExecutorService exServiceRxmtLsr;
87 private ScheduledExecutorService exServiceFlooding;
88 private ScheduledExecutorService exServiceRxmtDDPacket;
89 private ScheduledExecutorService exServiceInActivity;
90
91 private boolean floodingTimerScheduled = false;
92 private boolean rxmtLsrTimerScheduled = false;
93 private boolean rxmtDdPacketTimerScheduled = false;
94 private boolean inActivityTimerScheduled = false;
95
96 /**
97 * When the two neighbors are exchanging databases, they form a master/slave relationship.
98 * The master sends the first Database Description Packet
99 */
100 private int isMaster;
101
102 /**
103 * The DD Sequence Number of the DD packet that is currently being sent to the neighbor.
104 */
105 private long ddSeqNum;
106
107 /**
108 * Another data structure for keeping information of the last received DD packet.
109 */
110 private DdPacket lastDdPacket;
111
112 /**
113 * Another data structure for keeping information of the last Sent DD packet.
114 */
115 private DdPacket lastSentDdPacket;
116
117 /**
118 * Another data structure for keeping information of the last Sent LSrequest packet.
119 */
120 private LsRequest lastSentLsrPacket;
121
122 /**
123 * The router ID of the Neighbor Router.
124 */
125 private Ip4Address neighborId;
126
127 /**
128 * The IP address of the neighboring router's interface to the attached network.
129 */
130 private Ip4Address neighborIpAddr;
131
132 /**
133 * The neighbor's IDEA of the designated router.
134 */
135 private Ip4Address neighborDr;
136
137 /**
138 * The neighbor's IDEA of the backup designated router.
139 */
140 private Ip4Address neighborBdr;
141
142 private int routerPriority;
143 private int routerDeadInterval;
144
145 /**
146 * The list of LSAs that have to be flooded.
147 */
Ray Milkey019fba42018-01-31 14:07:47 -0800148 private Map<String, OspfLsa> reTxList = new LinkedHashMap<>();
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530149
150 /**
151 * The list of LSAs that have been flooded but not yet acknowledged on this adjacency.
152 */
Ray Milkey019fba42018-01-31 14:07:47 -0800153 private Map<String, OspfLsa> pendingReTxList = new LinkedHashMap<>();
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530154
155 /**
156 * List of LSAs which are failed to received ACK.
157 */
Ray Milkey019fba42018-01-31 14:07:47 -0800158 private Map failedTxList = new HashMap<>();
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530159
160 /**
161 * The complete list of LSAs that make up the area link-state database, at the moment the.
162 * neighbor goes into Database Exchange state (EXCHANGE).
163 */
Ray Milkey019fba42018-01-31 14:07:47 -0800164 private List<LsaHeader> ddSummaryList = new CopyOnWriteArrayList<>();
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530165
166 /**
167 * LSA Request List from Neighbor.
168 */
169 private Hashtable lsReqList = new Hashtable();
170
171 /**
172 * The optional OSPF capabilities supported by the neighbor.
173 */
174 private int options;
175 private boolean isOpaqueCapable;
176
177 /**
178 * A link to the OSPF-Interface this Neighbor belongs to.
179 */
180 private OspfInterface ospfInterface;
181
182 /**
183 * A link to the OSPF-Area this Neighbor Data Structure belongs to.
184 */
185 private OspfArea ospfArea;
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530186 private List<TopLevelTlv> topLevelTlvs = new ArrayList<>();
187 private List<DeviceInformation> deviceInformationList = new ArrayList<>();
188
189 private TopologyForDeviceAndLink topologyForDeviceAndLink;
190
191 /**
192 * Creates an instance of Neighbor.
193 *
194 * @param paramOspfArea OSPF Area instance
195 * @param paramOspfInterface OSPF interface instance
196 * @param ipAddr IP address
197 * @param routerId router id
198 * @param options options
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530199 * @param topologyForDeviceAndLinkCommon topology for device and link instance
200 */
201 public OspfNbrImpl(OspfArea paramOspfArea, OspfInterface paramOspfInterface,
202 Ip4Address ipAddr, Ip4Address routerId, int options,
sunishvkf7c56552016-07-18 16:02:39 +0530203 TopologyForDeviceAndLink topologyForDeviceAndLinkCommon) {
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530204 this.ospfArea = paramOspfArea;
205 this.ospfInterface = paramOspfInterface;
206 state = OspfNeighborState.DOWN;
207 isMaster = OspfUtil.NOT_MASTER;
208 ddSeqNum = OspfUtil.createRandomNumber();
209 neighborIpAddr = ipAddr;
210 neighborId = routerId;
211 this.options = options;
212 lastDdPacket = new DdPacket();
213 routerDeadInterval = paramOspfInterface.routerDeadIntervalTime();
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530214 this.topologyForDeviceAndLink = topologyForDeviceAndLinkCommon;
215 }
216
217 /**
218 * Gets the IP address of this neighbor.
219 *
220 * @return the IP address of this neighbor
221 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -0800222 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530223 public Ip4Address neighborIpAddr() {
224 return neighborIpAddr;
225 }
226
227 /**
228 * Gets the neighbor is opaque enabled or not.
229 *
230 * @return true if the neighbor is opaque enabled else false.
231 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -0800232 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530233 public boolean isOpaqueCapable() {
234 return isOpaqueCapable;
235 }
236
237 /**
238 * Sets the neighbor is opaque enabled or not.
239 *
240 * @param isOpaqueCapable true if the neighbor is opaque enabledelse false
241 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -0800242 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530243 public void setIsOpaqueCapable(boolean isOpaqueCapable) {
244 this.isOpaqueCapable = isOpaqueCapable;
245 }
246
247 /**
sunishvkf7c56552016-07-18 16:02:39 +0530248 * Sets router dead interval.
249 *
250 * @param routerDeadInterval router dead interval
251 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -0800252 @Override
sunishvkf7c56552016-07-18 16:02:39 +0530253 public void setRouterDeadInterval(int routerDeadInterval) {
254 this.routerDeadInterval = routerDeadInterval;
255 }
256
257 /**
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530258 * Have seen a Neighbor, but the Neighbor doesn't know about me.
259 *
260 * @param ospfHello Hello Packet instance
261 * @param channel netty channel instance
262 */
263 public void oneWayReceived(OspfMessage ospfHello, Channel channel) {
264 log.debug("OSPFNbr::oneWayReceived...!!!");
265 stopInactivityTimeCheck();
266 startInactivityTimeCheck();
267
268 if (state == OspfNeighborState.ATTEMPT) {
269 state = OspfNeighborState.INIT;
270 } else if (state == OspfNeighborState.DOWN) {
271 state = OspfNeighborState.INIT;
272 }
273
274 if (state.getValue() >= OspfNeighborState.TWOWAY.getValue()) {
275 state = OspfNeighborState.INIT;
276 failedTxList.clear();
277 ddSummaryList.clear();
278 lsReqList.clear();
279 }
280 }
281
282 /**
283 * Called when a DD OSPFMessage is received while state was INIT.
284 *
285 * @param ospfMessage ospf message instance
286 * @param channel netty channel instance
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530287 */
Ray Milkey019fba42018-01-31 14:07:47 -0800288 public void twoWayReceived(OspfMessage ospfMessage, Channel channel) {
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530289 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
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530370 */
371 public void negotiationDone(OspfMessage ospfMessage,
Ray Milkey019fba42018-01-31 14:07:47 -0800372 boolean neighborIsMaster, List payload, Channel ch) {
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530373 stopRxMtDdTimer();
374 OspfPacketHeader packet = (OspfPacketHeader) ospfMessage;
375 DdPacket ddPacketForCheck = (DdPacket) packet;
376 if (ddPacketForCheck.isOpaqueCapable()) {
377 OspfLsdb database = ospfArea.database();
378 List opaqueLsas = database.getAllLsaHeaders(true, true);
379 Iterator iterator = opaqueLsas.iterator();
380 while (iterator.hasNext()) {
381 OspfLsa ospfLsa = (OspfLsa) iterator.next();
382 if (ospfLsa.getOspfLsaType() == OspfLsaType.AREA_LOCAL_OPAQUE_LSA) {
383 OpaqueLsa10 opaqueLsa10 = (OpaqueLsa10) ospfLsa;
384 topLevelTlvs = opaqueLsa10.topLevelValues();
385 }
386 }
387 }
388 if (state == OspfNeighborState.EXSTART) {
389 state = OspfNeighborState.EXCHANGE;
390 boolean excludeMaxAgeLsa = true;
391 //list of contents of area wise LSA
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -0800392 ddSummaryList = ospfArea.getLsaHeaders(excludeMaxAgeLsa, isOpaqueCapable);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530393
394 if (neighborIsMaster) {
395 processLsas(payload);
396 // ...construct new DD Packet...
397 DdPacket ddPacket = new DdPacket();
398 // setting OSPF Header
399 ddPacket.setOspfVer(OspfUtil.OSPF_VERSION);
400 ddPacket.setOspftype(OspfPacketType.DD.value());
401 ddPacket.setRouterId(ospfArea.routerId());
402 ddPacket.setAreaId(ospfArea.areaId());
403 ddPacket.setAuthType(OspfUtil.NOT_ASSIGNED);
404 ddPacket.setAuthentication(OspfUtil.NOT_ASSIGNED);
405 ddPacket.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
406 ddPacket.setChecksum(OspfUtil.NOT_ASSIGNED);
407 boolean isOpaqueEnabled = ospfArea.isOpaqueEnabled();
408 if (isOpaqueEnabled && isOpaqueCapable) {
409 ddPacket.setOptions(ospfArea.opaqueEnabledOptions());
410 } else {
411 ddPacket.setOptions(ospfArea.options());
412 }
413 ddPacket.setIsInitialize(OspfUtil.INITIALIZE_NOTSET);
414 ddPacket.setIsMore(OspfUtil.MORE_NOTSET);
415 ddPacket.setIsMaster(OspfUtil.NOT_MASTER);
416 ddPacket.setImtu(ospfInterface.mtu());
417 ddPacket.setSequenceNo(ddSeqNum);
418 //setting the destination
419 ddPacket.setDestinationIp(packet.sourceIp());
420 setLastSentDdPacket(ddPacket);
421 getIsMoreBit();
422
sunishvkf7c56552016-07-18 16:02:39 +0530423 byte[] messageToWrite = getMessage(lastSentDdPacket);
424 ch.write(messageToWrite);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530425 } else {
426 // process LSA Vector's List, Add it to LSRequestList.
427 processLsas(payload);
428 DdPacket ddPacket = new DdPacket();
429 // setting OSPF Header
430 ddPacket.setOspfVer(OspfUtil.OSPF_VERSION);
431 ddPacket.setOspftype(OspfPacketType.DD.value());
432 ddPacket.setRouterId(ospfArea.routerId());
433 ddPacket.setAreaId(ospfArea.areaId());
434 ddPacket.setAuthType(OspfUtil.NOT_ASSIGNED);
435 ddPacket.setAuthentication(OspfUtil.NOT_ASSIGNED);
436 ddPacket.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
437 ddPacket.setChecksum(OspfUtil.NOT_ASSIGNED);
438 boolean isOpaqueEnabled = ospfArea.isOpaqueEnabled();
439 if (isOpaqueEnabled && isOpaqueCapable) {
440 ddPacket.setOptions(ospfArea.opaqueEnabledOptions());
441 } else {
442 ddPacket.setOptions(ospfArea.options());
443 }
444 ddPacket.setIsInitialize(OspfUtil.INITIALIZE_NOTSET);
445 ddPacket.setIsMore(OspfUtil.MORE_NOTSET);
446 ddPacket.setIsMaster(OspfUtil.IS_MASTER);
447 ddPacket.setImtu(ospfInterface.mtu());
448 ddPacket.setSequenceNo(ddSeqNum);
449 setLastSentDdPacket(ddPacket);
450 getIsMoreBit();
451 ddPacket.setDestinationIp(packet.sourceIp());
sunishvkf7c56552016-07-18 16:02:39 +0530452 byte[] messageToWrite = getMessage(lastSentDdPacket);
453 ch.write(messageToWrite);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530454 startRxMtDdTimer(ch);
455 }
456 }
457 }
458
459 /**
460 * Process the LSA Headers received in the last received Database Description OSPFMessage.
461 *
462 * @param ddPayload LSA headers to process
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530463 */
Ray Milkey019fba42018-01-31 14:07:47 -0800464 public void processLsas(List ddPayload) {
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530465 log.debug("OSPFNbr::processLsas...!!!");
466 OspfLsa nextLsa;
467 Iterator lsas = ddPayload.iterator();
468 while (lsas.hasNext()) {
469 nextLsa = (OspfLsa) lsas.next();
470 // check LSA Type.
471 if (((nextLsa.getOspfLsaType().value() > OspfLsaType.EXTERNAL_LSA.value()) &&
472 (nextLsa.getOspfLsaType().value() < OspfLsaType.LINK_LOCAL_OPAQUE_LSA.value())) ||
473 (nextLsa.getOspfLsaType().value() > OspfLsaType.AS_OPAQUE_LSA.value())) {
474 // unknown lsType found!
475 seqNumMismatch("LS Type found was unknown.");
476 return;
477 }
478
479 if ((nextLsa.getOspfLsaType() == OspfLsaType.EXTERNAL_LSA) &&
480 !ospfArea.isExternalRoutingCapability()) {
481 // LSA is external and the Area has no external lsa capability
482 seqNumMismatch("External LSA found although area is stub.");
483 return;
484 }
485
486 LsaWrapper lsaHasInstance = ospfArea.lsaLookup(nextLsa);
487 if (lsaHasInstance == null) {
488 lsReqList.put(((OspfAreaImpl) ospfArea).getLsaKey((LsaHeader) nextLsa), nextLsa);
489 } else {
490 String isNew = ((OspfAreaImpl) ospfArea).isNewerOrSameLsa(nextLsa,
491 lsaHasInstance.ospfLsa());
492 if (isNew.equals("latest")) {
493 lsReqList.put(((OspfAreaImpl) ospfArea).getLsaKey((LsaHeader) nextLsa), nextLsa);
494 }
495 }
496 }
497 }
498
499 /**
500 * Handles sequence number mis match event.
501 *
502 * @param reason a string represents the mismatch reason
503 * @return OSPF message instance
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530504 */
Ray Milkey019fba42018-01-31 14:07:47 -0800505 public OspfMessage seqNumMismatch(String reason) {
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530506 log.debug("OSPFNbr::seqNumMismatch...{} ", reason);
507 stopRxMtDdTimer();
508
509 if (state.getValue() >= OspfNeighborState.EXCHANGE.getValue()) {
510 /* if (state == OspfNeighborState.FULL) {
511 ospfArea.refreshArea(ospfInterface);
512 }*/
513
514 state = OspfNeighborState.EXSTART;
515 lsReqList.clear();
516 ddSummaryList.clear();
517 //increment the dd sequence number
518 ddSeqNum++;
519
520 DdPacket ddPacket = new DdPacket();
521 // seting OSPF Header
522 ddPacket.setOspfVer(OspfUtil.OSPF_VERSION);
523 ddPacket.setOspftype(OspfPacketType.DD.value());
524 ddPacket.setRouterId(ospfArea.routerId());
525 ddPacket.setAreaId(ospfArea.areaId());
526 ddPacket.setAuthType(OspfUtil.NOT_ASSIGNED);
527 ddPacket.setAuthentication(OspfUtil.NOT_ASSIGNED);
528 ddPacket.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
529 ddPacket.setChecksum(OspfUtil.NOT_ASSIGNED);
530 boolean isOpaqueEnabled = ospfArea.isOpaqueEnabled();
531 if (isOpaqueEnabled) {
532 ddPacket.setOptions(ospfArea.opaqueEnabledOptions());
533 } else {
534 ddPacket.setOptions(ospfArea.options());
535 }
536 ddPacket.setIsInitialize(OspfUtil.INITIALIZE_SET);
537 ddPacket.setIsMore(OspfUtil.MORE_SET);
538 ddPacket.setIsMaster(OspfUtil.IS_MASTER);
539 ddPacket.setImtu(ospfInterface.mtu());
540 ddPacket.setSequenceNo(ddSeqNum);
541
542 setLastSentDdPacket(ddPacket);
543 //setting destination ip
544 ddPacket.setDestinationIp(neighborIpAddr());
545 setLastSentDdPacket(ddPacket);
546
547 return ddPacket;
548 }
549
550 return null;
551 }
552
553 /**
554 * Called if a LS Request has been received for an LSA which is not contained in the database.
555 * This indicates an error in the Database Exchange process.
556 * Actions to be performed are the same as in seqNumMismatch.
557 * In addition, stop the possibly activated re transmission timer.
558 *
559 * @param ch netty channel instance
560 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -0800561 @Override
Ray Milkey019fba42018-01-31 14:07:47 -0800562 public void badLSReq(Channel ch) {
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530563 log.debug("OSPFNbr::badLSReq...!!!");
564
565 if (state.getValue() >= OspfNeighborState.EXCHANGE.getValue()) {
566 if (state == OspfNeighborState.FULL) {
567 ospfArea.refreshArea(ospfInterface);
568 }
569
570 stopRxMtDdTimer();
571 state = OspfNeighborState.EXSTART;
572
573 lsReqList.clear();
574 ddSummaryList.clear();
575 reTxList.clear();
576 //increment the dd sequence number
577 isMaster = OspfUtil.IS_MASTER;
578 ddSeqNum++;
579 DdPacket ddPacket = new DdPacket();
580 // seting OSPF Header
581 ddPacket.setOspfVer(OspfUtil.OSPF_VERSION);
582 ddPacket.setOspftype(OspfPacketType.DD.value());
583 ddPacket.setRouterId(ospfArea.routerId());
584 ddPacket.setAreaId(ospfArea.areaId());
585 ddPacket.setAuthType(OspfUtil.NOT_ASSIGNED);
586 ddPacket.setAuthentication(OspfUtil.NOT_ASSIGNED);
587 ddPacket.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
588 ddPacket.setChecksum(OspfUtil.NOT_ASSIGNED);
589
590 // setting DD Body
591 boolean isOpaqueEnabled = ospfArea.isOpaqueEnabled();
592 if (isOpaqueEnabled && this.isOpaqueCapable) {
593 ddPacket.setOptions(ospfArea.opaqueEnabledOptions());
594 } else {
595 ddPacket.setOptions(ospfArea.options());
596 }
597 ddPacket.setIsInitialize(OspfUtil.INITIALIZE_SET);
598 ddPacket.setIsMore(OspfUtil.MORE_SET);
599 ddPacket.setIsMaster(OspfUtil.IS_MASTER);
600 ddPacket.setImtu(ospfInterface.mtu());
601 ddPacket.setSequenceNo(ddSeqNum);
602
603 rxmtDdPacketTask = new InternalRxmtDdPacket(ch);
604 startRxMtDdTimer(ch);
605
606 //setting destination ip
607 ddPacket.setDestinationIp(neighborIpAddr());
608 setLastSentDdPacket(ddPacket);
sunishvkf7c56552016-07-18 16:02:39 +0530609 byte[] messageToWrite = getMessage(ddPacket);
610 ch.write(messageToWrite);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530611 }
612 }
613
614 /**
615 * Called if state is EXCHANGE. This method is executed every time a DD Packets arrives.
616 * When the last Packet arrives, it transfers the state into LOADING or FULL
617 *
618 * @param neighborIsMaster true if neighbor is master else false
619 * @param dataDescPkt DdPacket instance
620 * @param ch netty channel instance
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530621 */
622 public void processDdPacket(boolean neighborIsMaster, DdPacket dataDescPkt,
Ray Milkey019fba42018-01-31 14:07:47 -0800623 Channel ch) {
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530624 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 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -0800840 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530841 public void adjOk(Channel ch) {
842 log.debug("OSPFNbr::adjOk...!!!");
843 if (ospfInterface.interfaceType() != OspfInterfaceType.POINT_TO_POINT.value()) {
844 if (state == OspfNeighborState.TWOWAY) {
845 if (formAdjacencyOrNot()) {
846 state = OspfNeighborState.EXSTART;
847 //check for sequence number in lsdb
848 ddSeqNum++;
849
850 DdPacket ddPacket = new DdPacket();
851 // seting OSPF Header
852 ddPacket.setOspfVer(OspfUtil.OSPF_VERSION);
853 ddPacket.setOspftype(OspfPacketType.DD.value());
854 ddPacket.setRouterId(ospfArea.routerId());
855 ddPacket.setAreaId(ospfArea.areaId());
856 ddPacket.setAuthType(OspfUtil.NOT_ASSIGNED);
857 ddPacket.setAuthentication(OspfUtil.NOT_ASSIGNED);
858 ddPacket.setOspfPacLength(OspfUtil.NOT_ASSIGNED);
859 ddPacket.setChecksum(OspfUtil.NOT_ASSIGNED);
860
861 // setting DD Body
862 boolean isOpaqueEnabled = ospfArea.isOpaqueEnabled();
863 if (isOpaqueEnabled && this.isOpaqueCapable) {
864 ddPacket.setOptions(ospfArea.opaqueEnabledOptions());
865 } else {
866 ddPacket.setOptions(ospfArea.options());
867 }
868 ddPacket.setIsInitialize(OspfUtil.INITIALIZE_SET);
869 ddPacket.setIsMore(OspfUtil.MORE_SET);
870 ddPacket.setIsMaster(OspfUtil.IS_MASTER);
871 ddPacket.setImtu(ospfInterface.mtu());
872 ddPacket.setSequenceNo(ddSeqNum);
873 rxmtDdPacketTask = new InternalRxmtDdPacket(ch);
874 startRxMtDdTimer(ch);
875 //setting destination ip
876 ddPacket.setDestinationIp(neighborIpAddr());
877 setLastSentDdPacket(ddPacket);
sunishvkf7c56552016-07-18 16:02:39 +0530878 byte[] messageToWrite = getMessage(ddPacket);
879 ch.write(messageToWrite);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530880 }
881 } else if (state.getValue() >= OspfNeighborState.EXSTART.getValue()) {
882 if (!formAdjacencyOrNot()) {
883 state = OspfNeighborState.TWOWAY;
884 lsReqList.clear();
885 ddSummaryList.clear();
886 reTxList.clear();
887 }
888 }
889 }
890 }
891
892 /**
893 * LS Update Packet has been received while state was EXCHANGE or LOADING.
894 * Examine the received LSAs, check whether they were requested or not and process
895 * them accordingly. Therefore use method "processReceivedLsa" for further treatment.
896 *
897 * @param lsUpdPkt LS Update Packet received while Neighbor state was EXCHANGE or
898 * LOADING
899 * @param ch netty channel instance
Ray Milkey019fba42018-01-31 14:07:47 -0800900 * @throws OspfParseException on parsing error
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530901 */
Ray Milkey019fba42018-01-31 14:07:47 -0800902 public void processLsUpdate(LsUpdate lsUpdPkt, Channel ch) throws OspfParseException {
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530903 stopRxMtLsrTimer();
904 log.debug("OSPFNbr::processLsUpdate...!!!");
905
906 List lsaList = lsUpdPkt.getLsaList();
907 if (!lsaList.isEmpty()) {
908 Iterator itr = lsaList.iterator();
909
910 while (itr.hasNext()) {
911 LsaHeader lsaHeader = (LsaHeader) itr.next();
912 String key = ((OspfAreaImpl) ospfArea).getLsaKey(lsaHeader);
913
914 if (lsReqList.containsKey(key)) {
915 boolean removeIt;
916 removeIt = processReceivedLsa(lsaHeader, false, ch,
917 lsUpdPkt.sourceIp());
918 if (removeIt) {
919 lsReqList.remove(key);
920 }
921 } else {
922 // LSA was received via Flooding
923 processReceivedLsa(lsaHeader, true, ch,
924 lsUpdPkt.sourceIp());
925 }
926 }
927
928 if (lsReqList.isEmpty() && (state == OspfNeighborState.LOADING)) {
929 // loading complete
930 loadingDone();
931 } else {
932 stopRxMtLsrTimer();
933 LsRequest lsRequest = buildLsRequest();
934 lsRequest.setDestinationIp(lsUpdPkt.sourceIp());
935 setLastSentLsrPacket(lsRequest);
936
937 startRxMtLsrTimer(ch);
938 }
939 }
940 }
941
942 /***
943 * Method gets called when no more ls request list and moving to FULL State.
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530944 */
Ray Milkey019fba42018-01-31 14:07:47 -0800945 public void loadingDone() {
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530946 stopRxMtLsrTimer();
947 stopRxMtDdTimer();
948 log.debug("OSPFNbr::loadingDone...!!!");
949 state = OspfNeighborState.FULL;
950 ospfArea.refreshArea(ospfInterface);
951 }
952
953 /**
954 * Adds device and link.
955 *
956 * @param topologyForDeviceAndLink topology for device and link instance
957 */
958 private void callDeviceAndLinkAdding(TopologyForDeviceAndLink topologyForDeviceAndLink) {
959 Map<String, DeviceInformation> deviceInformationMap = topologyForDeviceAndLink.deviceInformationMap();
sunishvkf7c56552016-07-18 16:02:39 +0530960 Map<String, DeviceInformation> deviceInformationMapForPointToPoint =
961 topologyForDeviceAndLink.deviceInformationMapForPointToPoint();
962 Map<String, DeviceInformation> deviceInformationMapToDelete =
963 topologyForDeviceAndLink.deviceInformationMapToDelete();
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530964 Map<String, LinkInformation> linkInformationMap = topologyForDeviceAndLink.linkInformationMap();
sunishvkf7c56552016-07-18 16:02:39 +0530965 Map<String, LinkInformation> linkInformationMapForPointToPoint =
966 topologyForDeviceAndLink.linkInformationMapForPointToPoint();
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530967 OspfRouter ospfRouter = new OspfRouterImpl();
sunishvkf7c56552016-07-18 16:02:39 +0530968
969 if (deviceInformationMap.size() != 0) {
970 for (String key : deviceInformationMap.keySet()) {
971 DeviceInformation value = deviceInformationMap.get(key);
972 ospfRouter.setRouterIp(value.routerId());
973 ospfRouter.setAreaIdOfInterface(ospfArea.areaId());
974 ospfRouter.setNeighborRouterId(value.deviceId());
975 OspfDeviceTed ospfDeviceTed = new OspfDeviceTedImpl();
976 List<Ip4Address> ip4Addresses = value.interfaceId();
977 ospfDeviceTed.setIpv4RouterIds(ip4Addresses);
978 ospfRouter.setDeviceTed(ospfDeviceTed);
979 ospfRouter.setOpaque(ospfArea.isOpaqueEnabled());
980 if (value.isDr()) {
981 ospfRouter.setDr(value.isDr());
982 } else {
983 ospfRouter.setDr(false);
984 }
985 int size = value.interfaceId().size();
986 for (int i = 0; i < size; i++) {
987 ospfRouter.setInterfaceId(value.interfaceId().get(i));
988 }
989 ((OspfInterfaceImpl) ospfInterface).addDeviceInformation(ospfRouter);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +0530990 }
sunishvkf7c56552016-07-18 16:02:39 +0530991 }
992 if (deviceInformationMapForPointToPoint.size() != 0) {
993 for (String key : deviceInformationMapForPointToPoint.keySet()) {
994 DeviceInformation value = deviceInformationMapForPointToPoint.get(key);
995 ospfRouter.setRouterIp(value.routerId());
996 ospfRouter.setAreaIdOfInterface(ospfArea.areaId());
997 ospfRouter.setNeighborRouterId(value.deviceId());
998 OspfDeviceTed ospfDeviceTed = new OspfDeviceTedImpl();
999 List<Ip4Address> ip4Addresses = value.interfaceId();
1000 ospfDeviceTed.setIpv4RouterIds(ip4Addresses);
1001 ospfRouter.setDeviceTed(ospfDeviceTed);
1002 ospfRouter.setOpaque(value.isDr());
1003 int size = value.interfaceId().size();
1004 for (int i = 0; i < size; i++) {
1005 ospfRouter.setInterfaceId(value.interfaceId().get(i));
1006 }
1007 ((OspfInterfaceImpl) ospfInterface).addDeviceInformation(ospfRouter);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301008 }
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301009 }
1010 for (Map.Entry<String, LinkInformation> entry : linkInformationMap.entrySet()) {
1011 String key = entry.getKey();
1012 LinkInformation value = entry.getValue();
1013 OspfRouter ospfRouterForLink = new OspfRouterImpl();
1014 ospfRouterForLink.setInterfaceId(value.interfaceIp());
1015 ospfRouterForLink.setAreaIdOfInterface(ospfArea.areaId());
1016 ospfRouterForLink.setOpaque(ospfArea.isOpaqueEnabled());
sunishvkf7c56552016-07-18 16:02:39 +05301017 OspfLinkTed ospfLinkTed = topologyForDeviceAndLink.getOspfLinkTedHashMap(
1018 value.linkDestinationId().toString());
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301019 if (ospfLinkTed == null) {
1020 ospfLinkTed = new OspfLinkTedImpl();
1021 ospfLinkTed.setMaximumLink(Bandwidth.bps(0));
1022 ospfLinkTed.setMaxReserved(Bandwidth.bps(0));
1023 ospfLinkTed.setTeMetric(0);
1024 }
1025
1026 if (!value.isLinkSrcIdNotRouterId()) {
1027 ospfRouterForLink.setRouterIp(value.linkSourceId());
1028 ospfRouterForLink.setNeighborRouterId(value.linkDestinationId());
1029 try {
sunishvkf7c56552016-07-18 16:02:39 +05301030 ((OspfInterfaceImpl) ospfInterface).addLinkInformation(ospfRouterForLink, ospfLinkTed);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301031 } catch (Exception e) {
sunishvkf7c56552016-07-18 16:02:39 +05301032 log.debug("Exception addLinkInformation: " + e.getMessage());
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301033 }
1034 }
1035 }
1036 }
1037
1038 // RFC 2328 Section 13 - partly as flooding procedure
1039
1040 /**
1041 * Processes the received Lsa.
1042 *
1043 * @param recLsa received Lsa
1044 * @param receivedViaFlooding received via flooding or not
1045 * @param ch channel instance
1046 * @param sourceIp source of this Lsa
Ray Milkey019fba42018-01-31 14:07:47 -08001047 * @throws OspfParseException on parsing error
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301048 * @return true to remove it from lsReqList else false
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301049 */
1050 public boolean processReceivedLsa(LsaHeader recLsa,
1051 boolean receivedViaFlooding, Channel ch, Ip4Address sourceIp)
Ray Milkey019fba42018-01-31 14:07:47 -08001052 throws OspfParseException {
Frank Wangd8ab0962017-08-11 11:09:30 +08001053 log.debug("OSPFNbr::processReceivedLsa(recLsa, receivedViaFlooding, ch)...!!!");
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301054
1055 //Validate the lsa checksum RFC 2328 13 (1)
1056 ChecksumCalculator checkSum = new ChecksumCalculator();
1057 if (!checkSum.isValidLsaCheckSum(recLsa,
1058 recLsa.getOspfLsaType().value(),
1059 OspfUtil.LSAPACKET_CHECKSUM_POS1,
1060 OspfUtil.LSAPACKET_CHECKSUM_POS2)) {
1061 log.debug("Checksum mismatch. Received LSA packet type {} ",
1062 recLsa.lsType());
1063
1064 return true;
1065 }
1066
1067 //If LSA type is unknown discard the lsa RFC 2328 13(2)
1068 if (((recLsa.getOspfLsaType().value() > OspfLsaType.EXTERNAL_LSA.value()) &&
1069 (recLsa.getOspfLsaType().value() < OspfLsaType.LINK_LOCAL_OPAQUE_LSA.value())) ||
1070 (recLsa.getOspfLsaType().value() > OspfLsaType.AS_OPAQUE_LSA.value())) {
1071 return true;
1072 }
1073
1074 //If LSA type is external & the area is configured as stub area discard the lsa RFC 2328 13(3)
1075 if ((recLsa.getOspfLsaType() == OspfLsaType.EXTERNAL_LSA) &&
sunish vkaa48da82016-03-02 23:17:06 +05301076 (!ospfArea.isExternalRoutingCapability())) {
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301077 return true;
1078 }
1079
1080 //if lsa age is equal to maxage && instance is not in lsdb && none of neighbors are in exchange
1081 // or loading state
1082 // Acknowledge the receipt by sending LSAck to the sender. 2328 13(4)
1083 if ((recLsa.age() == OspfParameters.MAXAGE) &&
1084 (ospfArea.lsaLookup(recLsa) == null) &&
1085 ospfArea.noNeighborInLsaExchangeProcess()) {
1086 // RFC 2328 Section 13. (4)
1087 // Because the LSA was not yet requested, it is treated as a flooded LSA and thus
1088 // acknowledged.
1089 directAcknowledge(recLsa, ch, sourceIp);
1090 return true;
1091 }
1092
1093 String key = ((OspfAreaImpl) ospfArea).getLsaKey(recLsa);
1094 LsaWrapper lsWrapper = ospfArea.lsaLookup(recLsa);
1095 String status = isNullorLatest(lsWrapper, recLsa);
1096 //Section 13 (5)
1097 if (status.equals("isNullorLatest")) {
1098
1099 if (recLsa.lsType() == OspfLsaType.ROUTER.value() && recLsa.advertisingRouter().equals(
1100 ospfArea.routerId())) {
1101 if (recLsa.lsSequenceNo() > ((LsaWrapperImpl) lsWrapper).lsaHeader().lsSequenceNo()) {
1102 ospfArea.setDbRouterSequenceNumber(recLsa.lsSequenceNo() + 1);
1103 processSelfOriginatedLsa();
1104 }
1105
1106 if (recLsa.age() == OspfParameters.MAXAGE) {
1107 ((LsaWrapperImpl) lsWrapper).lsaHeader().setAge(OspfParameters.MAXAGE);
1108 //remove from db & bin, add the lsa to MaxAge bin.
1109 ospfArea.addLsaToMaxAgeBin(((OspfAreaImpl) ospfArea).getLsaKey(((LsaWrapperImpl)
1110 lsWrapper).lsaHeader()), lsWrapper);
1111 ospfArea.removeLsaFromBin(lsWrapper);
1112 }
1113
1114 return true;
1115 } else if (recLsa.lsType() == OspfLsaType.NETWORK.value() && isLinkStateMatchesOwnRouterId(
1116 recLsa.linkStateId())) {
1117 // if we are not DR or if origination router ID not equal to our router ID //either
1118 // DR state changed or our router ID was changed
1119 //set LSAge = MaxAge
1120 //flood the LSA
1121 if (((OspfInterfaceImpl) ospfInterface).state() != OspfInterfaceState.DR ||
1122 !recLsa.advertisingRouter().equals(
1123 ospfArea.routerId())) {
1124 if (lsWrapper != null) {
1125 ((LsaWrapperImpl) lsWrapper).lsaHeader().setAge(OspfParameters.MAXAGE);
1126 //remove from bin, add the lsa to MaxAge bin.
1127 ospfArea.addLsaToMaxAgeBin(((OspfAreaImpl) ospfArea).getLsaKey(((LsaWrapperImpl)
1128 lsWrapper).lsaHeader()), lsWrapper);
1129 ospfArea.removeLsaFromBin(lsWrapper);
1130 } else {
1131 recLsa.setAge(OspfParameters.MAXAGE);
1132 ((OspfAreaImpl) ospfArea).addToOtherNeighborLsaTxList(recLsa);
1133 }
1134 }
1135
1136 return true;
1137 } else {
1138 if (recLsa.age() == OspfParameters.MAXAGE) {
1139 ((OspfInterfaceImpl) ospfInterface).addLsaHeaderForDelayAck(recLsa);
1140 //remove from db & bin, add the lsa to MaxAge bin.
1141 if (lsWrapper != null) {
1142 lsWrapper.setLsaAgeReceived(OspfParameters.MAXAGE);
1143 ospfArea.addLsaToMaxAgeBin(((OspfAreaImpl) ospfArea).getLsaKey(((LsaWrapperImpl)
1144 lsWrapper).lsaHeader()), lsWrapper);
1145 ospfArea.removeLsaFromBin(lsWrapper);
1146 } else {
1147 ((OspfAreaImpl) ospfArea).addToOtherNeighborLsaTxList(recLsa);
1148 }
1149
1150 return true;
1151 } else {
1152 ospfArea.addLsa(recLsa, ospfInterface);
1153 log.debug("Inside addLsaMethod");
1154 topologyForDeviceAndLink.addLocalDevice(recLsa, ospfInterface, ospfArea);
1155 callDeviceAndLinkAdding(topologyForDeviceAndLink);
1156 log.debug("Adding to lsdb interface State {}", ((OspfInterfaceImpl) ospfInterface).state().value());
1157 // should not send any acknowledge if flooded out on receiving interface
1158 if (((OspfInterfaceImpl) ospfInterface).state().value() == OspfInterfaceState.BDR.value()) {
1159 if (neighborDr.equals(sourceIp)) {
1160 log.debug("Adding for delayed ack {}", recLsa);
1161 ((OspfInterfaceImpl) ospfInterface).addLsaHeaderForDelayAck(recLsa);
1162 }
1163 } else {
1164 log.debug("Adding for delayed ack {}", recLsa);
1165 ((OspfInterfaceImpl) ospfInterface).addLsaHeaderForDelayAck(recLsa);
1166 }
1167
1168 if (((OspfInterfaceImpl) ospfInterface).state().value() == OspfInterfaceState.DR.value() ||
1169 ((OspfInterfaceImpl) ospfInterface).state().value() ==
1170 OspfInterfaceState.POINT2POINT.value()) {
1171 ((OspfAreaImpl) ospfArea).addToOtherNeighborLsaTxList(recLsa);
1172 }
1173 }
1174
1175 }
1176 }
1177 // RFC 2328 Section 13 (6)
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001178 if (lsReqList.containsValue(key)) {
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301179 badLSReq(ch);
1180 }
1181 if (status.equals("same")) { //13 (7)
1182 if (pendingReTxList.containsKey(key)) {
1183 pendingReTxList.remove(key);
1184 if (((OspfInterfaceImpl) ospfInterface).state().value() == OspfInterfaceState.BDR.value()) {
1185 if (neighborDr.equals(recLsa.advertisingRouter())) {
1186 ((OspfInterfaceImpl) ospfInterface).addLsaHeaderForDelayAck(recLsa);
1187 }
1188 }
1189 } else {
1190 directAcknowledge(recLsa, ch, sourceIp);
1191 return true;
1192 }
1193 } else if (status.equals("old")) { // section 13 - point 8
1194 if ((recLsa.lsSequenceNo() == OspfParameters.MAXSEQUENCENUMBER) &&
1195 (recLsa.age() == OspfParameters.MAXAGE)) {
1196 // section 13 - point 8
1197 // simple discard the received LSA -
1198 return true;
1199 } else {
1200 // respond back with the same LSA
1201 //Using flood LSA to sent the LSUpdate back to advertising router
1202 int diff = Math.abs(lsWrapper.lsaAgeReceived() - recLsa.age());
1203 if (diff > OspfParameters.MINLSARRIVAL) {
1204 sendLsa(((LsaWrapperImpl) lsWrapper).lsaHeader(), sourceIp, ch);
1205 }
1206 }
1207 }
sunishvkf7c56552016-07-18 16:02:39 +05301208
1209 constructDeviceInformationFromDb();
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301210 callDeviceAndLinkAdding(topologyForDeviceAndLink);
sunishvkf7c56552016-07-18 16:02:39 +05301211
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301212 return true;
1213 }
1214
1215 /**
sunishvkf7c56552016-07-18 16:02:39 +05301216 * Constructs device and link information from link state database.
1217 */
1218 private void constructDeviceInformationFromDb() {
1219 OspfLsdb database = ospfArea.database();
1220 List lsas = database.getAllLsaHeaders(true, true);
1221 Iterator iterator = lsas.iterator();
1222 while (iterator.hasNext()) {
1223 OspfLsa ospfLsa = (OspfLsa) iterator.next();
1224 if (ospfLsa.getOspfLsaType().value() == OspfLsaType.ROUTER.value()) {
1225 topologyForDeviceAndLink.addLocalDevice(ospfLsa, ospfInterface, ospfArea);
1226 } else if (ospfLsa.getOspfLsaType().value() == OspfLsaType.NETWORK.value()) {
1227 topologyForDeviceAndLink.addLocalDevice(ospfLsa, ospfInterface, ospfArea);
1228 }
1229 }
1230 }
1231
1232 /**
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301233 * Checks Link State ID is equal to one of the router's own IP interface addresses.
1234 *
1235 * @param linkStateId link state id
1236 * @return true if link state matches or false
1237 */
1238 private boolean isLinkStateMatchesOwnRouterId(String linkStateId) {
1239 boolean isLinkStateMatches = false;
sunishvkf7c56552016-07-18 16:02:39 +05301240 List<OspfInterface> interfaceLst = ospfArea.ospfInterfaceList();
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301241 for (OspfInterface ospfInterface : interfaceLst) {
1242 if (ospfInterface.ipAddress().toString().equals(linkStateId)) {
1243 isLinkStateMatches = true;
1244 break;
1245 }
1246 }
1247
1248 return isLinkStateMatches;
1249 }
1250
1251 /**
1252 * RFC 2328 Section 13 (5).
1253 *
1254 * @param lsWrapper ls wrapper instance
1255 * @param recLsa received LSA instance
1256 * @return returns a string status
1257 */
1258 public String isNullorLatest(LsaWrapper lsWrapper, LsaHeader recLsa) {
1259
1260
1261 if (lsWrapper != null) {
1262 LsaHeader ownLsa = (LsaHeader) lsWrapper.ospfLsa();
1263 String status = ospfArea.isNewerOrSameLsa(recLsa, ownLsa);
1264
1265 if (status.equals("latest")) {
1266 return "isNullorLatest";
1267 } else {
1268 return status;
1269 }
1270 } else {
1271 return "isNullorLatest";
1272 }
1273 }
1274
1275 /**
1276 * RFC 2328 section 13.4
1277 * Processing self-originated LSAs.
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301278 */
Ray Milkey019fba42018-01-31 14:07:47 -08001279 public void processSelfOriginatedLsa() {
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301280 ospfArea.refreshArea(ospfInterface);
1281 }
1282
1283 /**
1284 * Sends the LSA to destination address.
1285 *
1286 * @param lsa LSA instance to sent
1287 * @param destination destination IP address
1288 * @param ch netty channel instance
1289 */
1290 public void sendLsa(LsaHeader lsa, Ip4Address destination, Channel ch) {
1291 if (lsa == null) {
1292 return;
1293 }
1294
1295 LsUpdate responseLsUpdate = new LsUpdate();
1296 // seting OSPF Header
1297 responseLsUpdate.setOspfVer(OspfUtil.OSPF_VERSION);
1298 responseLsUpdate.setOspftype(OspfPacketType.LSUPDATE.value());
1299 responseLsUpdate.setRouterId(ospfArea.routerId());
1300 responseLsUpdate.setAreaId(ospfArea.areaId());
1301 responseLsUpdate.setAuthType(OspfUtil.NOT_ASSIGNED);
1302 responseLsUpdate.setAuthentication(OspfUtil.NOT_ASSIGNED);
1303 responseLsUpdate.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
1304 responseLsUpdate.setChecksum(OspfUtil.NOT_ASSIGNED);
1305 responseLsUpdate.setNumberOfLsa(1);
1306 responseLsUpdate.addLsa(lsa);
1307
1308 //setting the destination.
1309 responseLsUpdate.setDestinationIp(destination);
sunishvkf7c56552016-07-18 16:02:39 +05301310 byte[] messageToWrite = getMessage(responseLsUpdate);
1311 ch.write(messageToWrite);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301312 }
1313
1314 /**
1315 * Sends a direct Acknowledgment for a particular LSA to the Neighbor.
1316 *
1317 * @param ackLsa LSA instance
1318 * @param ch netty channel instance
1319 * @param sourceIp source IP address
1320 */
1321 public void directAcknowledge(LsaHeader ackLsa, Channel ch, Ip4Address sourceIp) {
1322 log.debug("OSPFNbr::directAcknowledge...!!!");
1323
1324 LsAcknowledge ackContent = new LsAcknowledge();
1325 // seting OSPF Header
1326 ackContent.setOspfVer(OspfUtil.OSPF_VERSION);
1327 ackContent.setOspftype(OspfPacketType.LSAACK.value());
1328 ackContent.setRouterId(ospfArea.routerId());
1329 ackContent.setAreaId(ospfArea.areaId());
1330 ackContent.setAuthType(OspfUtil.NOT_ASSIGNED);
1331 ackContent.setAuthentication(OspfUtil.NOT_ASSIGNED);
1332 ackContent.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
1333 ackContent.setChecksum(OspfUtil.NOT_ASSIGNED);
1334 ackContent.addLinkStateHeader(ackLsa);
1335 //setting the destination IP
1336 ackContent.setDestinationIp(sourceIp);
sunishvkf7c56552016-07-18 16:02:39 +05301337 byte[] messageToWrite = getMessage(ackContent);
1338 ch.write(messageToWrite);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301339 }
1340
1341 /**
1342 * Called when neighbor is down.
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301343 */
Ray Milkey019fba42018-01-31 14:07:47 -08001344 public void neighborDown() {
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301345 log.debug("Neighbor Down {} and NeighborId {}", neighborIpAddr,
1346 neighborId);
1347 stopInactivityTimeCheck();
1348 stopRxMtDdTimer();
1349 stopRxMtLsrTimer();
1350
1351 if (floodingTimerScheduled) {
1352 stopFloodingTimer();
1353 floodingTimerScheduled = false;
1354 }
1355
1356 state = OspfNeighborState.DOWN;
1357 ospfArea.refreshArea(ospfInterface);
1358 lsReqList.clear();
1359 ddSummaryList.clear();
1360 if (neighborIpAddr.equals(neighborBdr) ||
1361 neighborIpAddr.equals(neighborDr)) {
sunishvkf7c56552016-07-18 16:02:39 +05301362 ((OspfInterfaceImpl) ospfInterface).neighborChange();
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301363 }
1364 log.debug("Neighbor Went Down : "
1365 + this.neighborIpAddr + " , " + this.neighborId);
1366 removeDeviceDetails(this.neighborId);
1367 OspfRouter ospfRouter = new OspfRouterImpl();
1368 ospfRouter.setRouterIp(this.neighborId());
1369 ospfRouter.setInterfaceId(ospfInterface.ipAddress());
1370 ospfRouter.setAreaIdOfInterface(ospfArea.areaId());
1371 ospfRouter.setDeviceTed(new OspfDeviceTedImpl());
sunishvkf7c56552016-07-18 16:02:39 +05301372 ((OspfInterfaceImpl) ospfInterface).removeDeviceInformation(ospfRouter);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301373 removeDeviceDetails(this.neighborIpAddr);
1374 OspfRouter ospfRouter1 = new OspfRouterImpl();
1375 ospfRouter1.setRouterIp(this.neighborIpAddr);
1376 ospfRouter1.setInterfaceId(ospfInterface.ipAddress());
1377 ospfRouter1.setAreaIdOfInterface(ospfArea.areaId());
1378 ospfRouter1.setDeviceTed(new OspfDeviceTedImpl());
sunishvkf7c56552016-07-18 16:02:39 +05301379 ((OspfInterfaceImpl) ospfInterface).removeDeviceInformation(ospfRouter1);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301380 }
1381
1382 /**
1383 * Removes device details.
1384 *
1385 * @param routerId router id
1386 */
1387 private void removeDeviceDetails(Ip4Address routerId) {
1388 String key = "device:" + routerId;
1389 topologyForDeviceAndLink.removeDeviceInformationMap(key);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301390 }
1391
1392 /**
1393 * Starts the inactivity timer.
1394 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001395 @Override
sunishvkf7c56552016-07-18 16:02:39 +05301396 public void startInactivityTimeCheck() {
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301397 if (!inActivityTimerScheduled) {
1398 log.debug("OSPFNbr::startInactivityTimeCheck");
1399 inActivityTimeCheckTask = new InternalInactivityTimeCheck();
1400 exServiceInActivity = Executors.newSingleThreadScheduledExecutor();
1401 exServiceInActivity.scheduleAtFixedRate(inActivityTimeCheckTask, routerDeadInterval,
1402 routerDeadInterval, TimeUnit.SECONDS);
1403 inActivityTimerScheduled = true;
1404 }
1405 }
1406
1407 /**
1408 * Stops the inactivity timer.
1409 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001410 @Override
sunishvkf7c56552016-07-18 16:02:39 +05301411 public void stopInactivityTimeCheck() {
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301412 if (inActivityTimerScheduled) {
1413 log.debug("OSPFNbr::stopInactivityTimeCheck ");
1414 exServiceInActivity.shutdown();
1415 inActivityTimerScheduled = false;
1416 }
1417 }
1418
1419 /**
1420 * Starts the flooding timer.
1421 *
1422 * @param channel channel instance
1423 */
1424 public void startFloodingTimer(Channel channel) {
1425
1426 if (!floodingTimerScheduled) {
1427 log.debug("OSPFNbr::startFloodingTimer");
1428 floodingTask = new InternalFloodingTask(channel);
1429 exServiceFlooding = Executors.newSingleThreadScheduledExecutor();
1430 //Run every 5 seconds.
1431 exServiceFlooding.scheduleAtFixedRate(floodingTask, OspfParameters.START_NOW,
1432 OspfParameters.MINLSINTERVAL, TimeUnit.SECONDS);
1433 floodingTimerScheduled = true;
1434 }
1435 }
1436
1437 /**
1438 * Stops the flooding timer.
1439 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001440 @Override
sunishvkf7c56552016-07-18 16:02:39 +05301441 public void stopFloodingTimer() {
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301442 if (floodingTimerScheduled) {
1443 log.debug("OSPFNbr::stopFloodingTimer ");
1444 exServiceFlooding.shutdown();
1445 floodingTimerScheduled = false;
1446 }
1447 }
1448
1449 /**
1450 * Starts the Dd Retransmission executor task.
1451 *
1452 * @param ch netty channel instance
1453 */
1454 private void startRxMtDdTimer(Channel ch) {
1455 if (!rxmtDdPacketTimerScheduled) {
1456 long retransmitInterval = ospfInterface.reTransmitInterval();
1457 rxmtDdPacketTask = new InternalRxmtDdPacket(ch);
1458 exServiceRxmtDDPacket = Executors.newSingleThreadScheduledExecutor();
1459 exServiceRxmtDDPacket.scheduleAtFixedRate(rxmtDdPacketTask, retransmitInterval,
1460 retransmitInterval, TimeUnit.SECONDS);
1461 rxmtDdPacketTimerScheduled = true;
1462 }
1463 }
1464
1465 /**
1466 * Stops the Dd Retransmission executor task.
1467 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001468 @Override
sunishvkf7c56552016-07-18 16:02:39 +05301469 public void stopRxMtDdTimer() {
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301470 if (rxmtDdPacketTimerScheduled) {
1471 exServiceRxmtDDPacket.shutdown();
1472 rxmtDdPacketTimerScheduled = false;
1473 }
1474 }
1475
1476 /**
1477 * Starts Ls request retransmission executor task.
1478 *
1479 * @param ch Netty channel instance
1480 */
1481 private void startRxMtLsrTimer(Channel ch) {
1482 if (!rxmtLsrTimerScheduled) {
1483 log.debug("OSPFNbr::startRxMtLsrTimer...!!!");
1484 long retransmitIntrvl = ospfInterface.reTransmitInterval();
1485 rxmtLsrPacketTask = new InternalRxmtLsrPacket(ch);
1486 exServiceRxmtLsr = Executors.newSingleThreadScheduledExecutor();
1487 exServiceRxmtLsr.scheduleAtFixedRate(rxmtLsrPacketTask, retransmitIntrvl,
1488 retransmitIntrvl, TimeUnit.SECONDS);
1489 rxmtLsrTimerScheduled = true;
1490 }
1491 }
1492
1493 /**
1494 * Stops Ls request retransmission executor task.
1495 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001496 @Override
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 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001527 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301528 public Ip4Address neighborId() {
1529 return neighborId;
1530 }
1531
1532 /**
1533 * Sets the neighbor id.
1534 *
1535 * @param neighborId neighbor id
1536 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001537 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301538 public void setNeighborId(Ip4Address neighborId) {
1539 this.neighborId = neighborId;
1540 }
1541
1542 /**
1543 * Gets the neighbor DR address.
1544 *
1545 * @return neighbor DR address
1546 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001547 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301548 public Ip4Address neighborDr() {
1549 return neighborDr;
1550 }
1551
1552 /**
1553 * Sets the neighbor DR address.
1554 *
1555 * @param neighborDr neighbor DR address
1556 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001557 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301558 public void setNeighborDr(Ip4Address neighborDr) {
1559 this.neighborDr = neighborDr;
1560 }
1561
1562 /**
1563 * Gets the neighbor BDR address.
1564 *
1565 * @return neighbor BDR address
1566 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001567 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301568 public Ip4Address neighborBdr() {
1569 return neighborBdr;
1570 }
1571
1572 /**
1573 * Sets the neighbor BDR address.
1574 *
1575 * @param neighborBdr neighbor BDR address
1576 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001577 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301578 public void setNeighborBdr(Ip4Address neighborBdr) {
1579 this.neighborBdr = neighborBdr;
1580 }
1581
1582 /**
1583 * Gets router priority.
1584 *
1585 * @return router priority
1586 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001587 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301588 public int routerPriority() {
1589 return routerPriority;
1590 }
1591
1592 /**
1593 * Sets router priority.
1594 *
1595 * @param routerPriority router priority
1596 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001597 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301598 public void setRouterPriority(int routerPriority) {
1599 this.routerPriority = routerPriority;
1600 }
1601
1602 /**
1603 * Gets the options value.
1604 *
1605 * @return options value
1606 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001607 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301608 public int options() {
1609 return options;
1610 }
1611
1612 /**
1613 * Sets the options value.
1614 *
1615 * @param options options value
1616 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001617 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301618 public void setOptions(int options) {
1619 this.options = options;
1620 }
1621
1622 /**
1623 * Gets the DD sequence number.
1624 *
1625 * @return DD sequence number
1626 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001627 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301628 public long ddSeqNum() {
1629 return ddSeqNum;
1630 }
1631
1632 /**
1633 * Sets the DD sequence number.
1634 *
1635 * @param ddSeqNum DD sequence number
1636 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001637 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301638 public void setDdSeqNum(long ddSeqNum) {
1639 this.ddSeqNum = ddSeqNum;
1640 }
1641
1642 /**
1643 * Gets neighbor is master or not.
1644 *
1645 * @return true if neighbor is master else false
1646 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001647 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301648 public int isMaster() {
1649 return isMaster;
1650 }
1651
1652 /**
1653 * Gets the last sent DD Packet.
1654 *
1655 * @return last sent DD Packet
1656 */
1657 public DdPacket lastSentDdPacket() {
1658 return lastSentDdPacket;
1659 }
1660
1661 /**
1662 * Sets the last sent DD Packet.
1663 *
1664 * @param lastSentDdPacket last sent DD Packet
1665 */
1666 public void setLastSentDdPacket(DdPacket lastSentDdPacket) {
1667 this.lastSentDdPacket = lastSentDdPacket;
1668 }
1669
1670 /**
1671 * Gets the last sent Ls Request Packet.
1672 *
1673 * @return last sent Ls Request Packet
1674 */
1675 public LsRequest getLastSentLsrPacket() {
1676 return lastSentLsrPacket;
1677 }
1678
1679 /**
1680 * Sets the last sent Ls Request Packet.
1681 *
1682 * @param lastSentLsrPacket last sent Ls Request Packet
1683 */
1684 public void setLastSentLsrPacket(LsRequest lastSentLsrPacket) {
1685 this.lastSentLsrPacket = lastSentLsrPacket;
1686 }
1687
1688 /**
1689 * Gets the neighbors state.
1690 *
1691 * @return neighbors state
1692 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001693 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301694 public OspfNeighborState getState() {
1695 return state;
1696 }
1697
1698 /**
1699 * Sets the neighbors state.
1700 *
1701 * @param state neighbors state
1702 */
1703 public void setState(OspfNeighborState state) {
1704 this.state = state;
1705 }
1706
1707 /**
1708 * Sets neighbor is master or not.
1709 *
1710 * @param isMaster neighbor is master or not
1711 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001712 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301713 public void setIsMaster(int isMaster) {
1714 this.isMaster = isMaster;
1715 }
1716
1717 /**
1718 * Gets the ls request list.
1719 *
1720 * @return ls request list
1721 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001722 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301723 public Hashtable getLsReqList() {
1724 return lsReqList;
1725 }
1726
1727 /**
1728 * Gets the reTxList instance.
1729 *
1730 * @return reTxList instance
1731 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001732 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301733 public Map getReTxList() {
1734 return reTxList;
1735 }
1736
1737 /**
1738 * Gets the pending re transmit list.
1739 *
1740 * @return pendingReTxList instance
1741 */
Yuta HIGUCHI488a94c2018-01-26 17:24:09 -08001742 @Override
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301743 public Map<String, OspfLsa> getPendingReTxList() {
1744 return pendingReTxList;
1745 }
1746
sunishvkf7c56552016-07-18 16:02:39 +05301747 /**
1748 * Gets message as bytes.
1749 *
1750 * @param ospfMessage OSPF message
1751 * @return OSPF message
1752 */
1753 private byte[] getMessage(OspfMessage ospfMessage) {
1754 OspfMessageWriter messageWriter = new OspfMessageWriter();
1755 if (((OspfInterfaceImpl) ospfInterface).state().equals(OspfInterfaceState.POINT2POINT)) {
1756 ospfMessage.setDestinationIp(OspfUtil.ALL_SPF_ROUTERS);
1757 }
1758 return (messageWriter.getMessage(ospfMessage, ospfInterface.interfaceIndex(),
1759 ((OspfInterfaceImpl) ospfInterface).state().value()));
1760 }
1761
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301762
1763 /**
1764 * Represents a Task which will do an inactivity time check.
1765 */
1766 private class InternalInactivityTimeCheck implements Runnable {
1767 /**
1768 * Constructor.
1769 */
1770 InternalInactivityTimeCheck() {
1771 }
1772
1773 @Override
1774 public void run() {
1775 try {
1776 log.debug("Neighbor Not Heard till the past router dead interval .");
1777 neighborDown();
1778 } catch (Exception e) {
1779 log.debug("Exception at inactivity time check...!!!");
1780 }
1781 }
1782 }
1783
1784 /**
1785 * Task which re transmits DdPacket every configured time interval.
1786 */
1787 private class InternalRxmtDdPacket implements Runnable {
1788 Channel ch;
1789
1790 /**
1791 * Creates an instance or Re transmit DD packet timer.
1792 *
1793 * @param ch netty channel instance
1794 */
1795 InternalRxmtDdPacket(Channel ch) {
1796 this.ch = ch;
1797 }
1798
1799 @Override
1800 public void run() {
1801 if ((ch != null) && ch.isConnected()) {
1802 DdPacket ddPacket = lastSentDdPacket();
sunishvkf7c56552016-07-18 16:02:39 +05301803 byte[] messageToWrite = getMessage(ddPacket);
1804 ch.write(messageToWrite);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301805 log.debug("Re-Transmit DD Packet .");
1806 } else {
1807 log.debug(
1808 "Re-Transmit DD Packet failed. Channel not connected..");
1809 }
1810 }
1811 }
1812
1813 /**
1814 * Task which re transmits Ls request Packet every configured time interval.
1815 */
1816 private class InternalRxmtLsrPacket implements Runnable {
1817 Channel ch;
1818
1819 /**
1820 * Creates an instance or Re transmit LS Request packet timer.
1821 *
1822 * @param ch netty channel instance
1823 */
1824 InternalRxmtLsrPacket(Channel ch) {
1825 this.ch = ch;
1826 }
1827
1828 @Override
1829 public void run() {
1830 if ((ch != null) && ch.isConnected()) {
1831 LsRequest lsrPacket = getLastSentLsrPacket();
sunishvkf7c56552016-07-18 16:02:39 +05301832 byte[] messageToWrite = getMessage(lsrPacket);
1833 ch.write(messageToWrite);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301834 log.debug("Re-Transmit LSRequest Packet .");
1835 } else {
1836 log.debug(
1837 "Re-Transmit LSRequest failed. Channel not connected..");
1838 }
1839 }
1840 }
1841
1842 /**
1843 * Task which transmits Ls update Packet based on the re transmit list.
1844 * every configured time interval.
1845 */
1846 private class InternalFloodingTask implements Runnable {
1847 Channel channel;
1848
1849 /**
1850 * Creates an instance or Flooding task.
1851 *
1852 * @param ch netty channel instance
1853 */
1854 InternalFloodingTask(Channel ch) {
1855 this.channel = ch;
1856 }
1857
1858 @Override
1859 public void run() {
1860 if ((channel != null) && channel.isConnected()) {
1861
1862 if ((pendingReTxList != null) && (pendingReTxList.size() > 0)) {
1863 List<LsUpdate> lsUpdateList = buildLsUpdate(pendingReTxList);
1864
1865 for (LsUpdate lsupdate : lsUpdateList) {
1866 //Pending for acknowledge directly sent it to neighbor
1867 lsupdate.setDestinationIp(neighborIpAddr);
sunishvkf7c56552016-07-18 16:02:39 +05301868 byte[] messageToWrite = getMessage(lsupdate);
1869 channel.write(messageToWrite);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301870 }
1871 }
1872
1873 if ((reTxList != null) && (reTxList.size() > 0)) {
1874 List<LsUpdate> lsUpdateList = buildLsUpdate(reTxList);
1875
1876 for (LsUpdate lsupdate : lsUpdateList) {
1877 //set the destination
1878 if ((((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.DR) ||
1879 (((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.POINT2POINT)) {
1880 lsupdate.setDestinationIp(OspfUtil.ALL_SPF_ROUTERS);
1881 } else if (((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.DROTHER ||
1882 (((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.BDR)) {
1883 lsupdate.setDestinationIp(neighborDr);
1884 }
sunishvkf7c56552016-07-18 16:02:39 +05301885 byte[] messageToWrite = getMessage(lsupdate);
1886 channel.write(messageToWrite);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301887 }
1888 }
1889 }
1890 }
1891
1892 /**
1893 * Builds the LsUpdate for flooding.
1894 *
1895 * @param txList list contains LSAs
1896 * @return list of LsUpdate instances
1897 */
1898 private List buildLsUpdate(Map<String, OspfLsa> txList) {
1899 List<LsUpdate> lsUpdateList = new ArrayList<>();
1900 ListIterator itr = new ArrayList(txList.keySet()).listIterator();
1901 while (itr.hasNext()) {
1902 LsUpdate lsupdate = new LsUpdate();
1903 // seting OSPF Header
1904 lsupdate.setOspfVer(OspfUtil.OSPF_VERSION);
1905 lsupdate.setOspftype(OspfPacketType.LSUPDATE.value());
1906 lsupdate.setRouterId(ospfArea.routerId());
1907 lsupdate.setAreaId(ospfArea.areaId());
1908 lsupdate.setAuthType(OspfUtil.NOT_ASSIGNED);
1909 lsupdate.setAuthentication(OspfUtil.NOT_ASSIGNED);
1910 lsupdate.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
1911 lsupdate.setChecksum(OspfUtil.NOT_ASSIGNED);
1912
1913 //limit to mtu
1914 int currentLength = OspfUtil.OSPF_HEADER_LENGTH + OspfUtil.FOUR_BYTES;
1915 int maxSize = ospfInterface.mtu() -
1916 OspfUtil.LSA_HEADER_LENGTH; // subtract a normal IP header.
1917
1918 int noLsa = 0;
1919 while (itr.hasNext()) {
1920
1921 String key = (String) itr.next();
1922 OspfLsa lsa = txList.get(key);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301923 if (lsa != null) {
Palash Kala9bf01a12017-03-30 14:08:55 +09001924 if ((lsa.age() + OspfParameters.INFTRA_NS_DELAY) >= OspfParameters.MAXAGE) {
1925 ((LsaHeader) lsa.lsaHeader()).setAge(OspfParameters.MAXAGE);
1926 } else {
1927 ((LsaHeader) lsa.lsaHeader()).setAge(lsa.age() + OspfParameters.INFTRA_NS_DELAY);
1928 }
1929
1930 if ((currentLength + ((LsaHeader) lsa.lsaHeader()).lsPacketLen()) >= maxSize) {
1931 itr.previous();
1932 break;
1933 }
1934 log.debug("FloodingTimer::LSA Type::{}, Header: {}, LSA: {}", lsa.getOspfLsaType(),
1935 lsa.lsaHeader(), lsa);
Kiran Ramachandra3d94a6c2016-02-17 16:57:03 +05301936 lsupdate.addLsa(lsa);
1937 noLsa++;
1938 currentLength = currentLength + ((LsaHeader) lsa.lsaHeader()).lsPacketLen();
1939 }
1940 log.debug("FloodingTimer::Removing key {}", key);
1941 if (txList.equals(reTxList)) {
1942 reTxList.remove(key);
1943 pendingReTxList.put(key, lsa);
1944 }
1945 }
1946 //set number of lsa's
1947 lsupdate.setNumberOfLsa(noLsa);
1948 lsUpdateList.add(lsupdate);
1949 }
1950 return lsUpdateList;
1951 }
1952 }
Ray Milkey0bb1e102016-11-10 14:51:27 -08001953}