blob: 79b613acaa8f21260941fed7c72e72e50a3ca755 [file] [log] [blame]
Kalyankumar Asangi27728f22016-02-17 15:46:28 +05301/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
Kalyankumar Asangi27728f22016-02-17 15:46:28 +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 */
16
17package org.onosproject.ospf.controller.area;
18
19import com.google.common.base.MoreObjects;
20import com.google.common.base.Objects;
sunishvkf7c56552016-07-18 16:02:39 +053021import org.jboss.netty.channel.Channel;
22import org.jboss.netty.channel.ChannelFuture;
23import org.jboss.netty.channel.ChannelHandlerContext;
Kalyankumar Asangi27728f22016-02-17 15:46:28 +053024import org.onlab.packet.Ip4Address;
sunishvkf7c56552016-07-18 16:02:39 +053025import org.onosproject.ospf.controller.LsaWrapper;
26import org.onosproject.ospf.controller.OspfArea;
Kalyankumar Asangi27728f22016-02-17 15:46:28 +053027import org.onosproject.ospf.controller.OspfInterface;
sunishvkf7c56552016-07-18 16:02:39 +053028import org.onosproject.ospf.controller.OspfLinkTed;
29import org.onosproject.ospf.controller.OspfLsa;
30import org.onosproject.ospf.controller.OspfMessage;
Kalyankumar Asangi27728f22016-02-17 15:46:28 +053031import org.onosproject.ospf.controller.OspfNbr;
sunishvkf7c56552016-07-18 16:02:39 +053032import org.onosproject.ospf.controller.OspfNeighborState;
33import org.onosproject.ospf.controller.OspfPacketType;
34import org.onosproject.ospf.controller.OspfRouter;
35import org.onosproject.ospf.controller.TopologyForDeviceAndLink;
36import org.onosproject.ospf.controller.impl.Controller;
37import org.onosproject.ospf.controller.impl.OspfNbrImpl;
38import org.onosproject.ospf.controller.impl.TopologyForDeviceAndLinkImpl;
39import org.onosproject.ospf.controller.lsdb.LsaWrapperImpl;
40import org.onosproject.ospf.controller.lsdb.OspfLsdbImpl;
41import org.onosproject.ospf.controller.util.OspfEligibleRouter;
42import org.onosproject.ospf.controller.util.OspfInterfaceType;
Kalyankumar Asangi27728f22016-02-17 15:46:28 +053043import org.onosproject.ospf.protocol.lsa.LsaHeader;
44import org.onosproject.ospf.protocol.lsa.OpaqueLsaHeader;
sunishvkf7c56552016-07-18 16:02:39 +053045import org.onosproject.ospf.protocol.ospfpacket.OspfMessageWriter;
46import 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.HelloPacket;
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;
Kalyankumar Asangi27728f22016-02-17 15:46:28 +053054import org.onosproject.ospf.protocol.util.OspfInterfaceState;
55import org.onosproject.ospf.protocol.util.OspfParameters;
sunishvkf7c56552016-07-18 16:02:39 +053056import org.onosproject.ospf.protocol.util.OspfUtil;
Kalyankumar Asangi27728f22016-02-17 15:46:28 +053057import org.slf4j.Logger;
58import org.slf4j.LoggerFactory;
59
60import java.util.ArrayList;
61import java.util.HashMap;
sunishvkf7c56552016-07-18 16:02:39 +053062import java.util.Iterator;
Kalyankumar Asangi27728f22016-02-17 15:46:28 +053063import java.util.List;
sunishvkf7c56552016-07-18 16:02:39 +053064import java.util.ListIterator;
65import java.util.Map;
Kalyankumar Asangi27728f22016-02-17 15:46:28 +053066import java.util.Set;
sunishvkf7c56552016-07-18 16:02:39 +053067import java.util.concurrent.ConcurrentHashMap;
68import java.util.concurrent.Executors;
69import java.util.concurrent.ScheduledExecutorService;
70import java.util.concurrent.ScheduledFuture;
71import java.util.concurrent.TimeUnit;
Kalyankumar Asangi27728f22016-02-17 15:46:28 +053072
73/**
74 * Representation of an OSPF interface.
75 */
76public class OspfInterfaceImpl implements OspfInterface {
77 private static final Logger log = LoggerFactory.getLogger(OspfInterfaceImpl.class);
sunishvkf7c56552016-07-18 16:02:39 +053078 private int interfaceIndex;
Kalyankumar Asangi27728f22016-02-17 15:46:28 +053079 private Ip4Address ipAddress;
80 private Ip4Address ipNetworkMask;
sunishvkf7c56552016-07-18 16:02:39 +053081 private Channel channel = null;
Kalyankumar Asangi27728f22016-02-17 15:46:28 +053082 private int helloIntervalTime;
83 private int routerDeadIntervalTime;
Kalyankumar Asangi27728f22016-02-17 15:46:28 +053084 private int routerPriority;
Kalyankumar Asangi27728f22016-02-17 15:46:28 +053085 private int interfaceType;
Kalyankumar Asangi27728f22016-02-17 15:46:28 +053086 private int mtu;
87 private int reTransmitInterval;
88 private Ip4Address dr;
89 private Ip4Address bdr;
90 private OspfInterfaceState state;
91 private List<LsaHeader> linkStateHeaders = new ArrayList<>();
sunishvkf7c56552016-07-18 16:02:39 +053092 private Map<String, OspfNbr> listOfNeighbors = new ConcurrentHashMap<>();
93 private Map<String, LsaHeader> listOfNeighborMap = new ConcurrentHashMap<>();
94 private long delay = 0;
95 private InternalHelloTimer helloTimerTask;
96 private InternalWaitTimer waitTimerTask;
97 private InternalDelayedAckTimer delayedAckTimerTask;
98 private ScheduledExecutorService exServiceHello;
99 private ScheduledExecutorService exServiceWait;
100 private ScheduledExecutorService exServiceDelayedAck;
101 private boolean isDelayedAckTimerScheduled = false;
102 private int delayedAckTimerInterval = 2500;
103 private int interfaceTypeOldValue = 0;
104 private TopologyForDeviceAndLink topologyForDeviceAndLink = new TopologyForDeviceAndLinkImpl();
105 private OspfArea ospfArea;
106 private Controller controller;
107
Kalyankumar Asangi27728f22016-02-17 15:46:28 +0530108
109 /**
110 * Gets the interface state.
111 *
112 * @return interfaceState state of the interface
113 */
114 public OspfInterfaceState state() {
115 return state;
116 }
117
118 /**
119 * Sets the interface state.
120 *
121 * @param ospfInterfaceState interface state enum instance
122 */
123 public void setState(OspfInterfaceState ospfInterfaceState) {
124 this.state = ospfInterfaceState;
125 }
126
127 /**
sunishvkf7c56552016-07-18 16:02:39 +0530128 * Sets the netty channel.
129 *
130 * @param channel channel
131 */
132 public void setChannel(Channel channel) {
133 this.channel = channel;
134 }
135
136 /**
137 * Returns OSPF area instance.
138 *
139 * @return OSPF area instance
140 */
141 public OspfArea ospfArea() {
142 return ospfArea;
143 }
144
145 /**
146 * Sets OSPF controller instance.
147 *
148 * @param controller OSPF controller instance
149 */
150 public void setController(Controller controller) {
151 this.controller = controller;
152 }
153
154 /**
155 * Sets OSPF area instance.
156 *
157 * @param ospfArea OSPF area instance
158 */
159 public void setOspfArea(OspfArea ospfArea) {
160 this.ospfArea = ospfArea;
161 }
162
163 /**
164 * Gets interface state.
165 *
166 * @return interface state
167 */
168 public String interfaceState() {
169 return state.interfaceState();
170 }
171
172 /**
Kalyankumar Asangi27728f22016-02-17 15:46:28 +0530173 * Gets link state headers.
174 *
175 * @return get the list of lsa headers
176 */
177 public List<LsaHeader> linkStateHeaders() {
178 Set<String> key = listOfNeighborMap.keySet();
179 for (String keys : key) {
180 LsaHeader lsaHeader = listOfNeighborMap.get(keys);
181 linkStateHeaders.add(lsaHeader);
182 }
183 return linkStateHeaders;
184 }
185
186 /**
187 * Gets IP network mask.
188 *
189 * @return network mask
190 */
191 public Ip4Address ipNetworkMask() {
192 return ipNetworkMask;
193 }
194
195 /**
196 * Sets IP network mask.
197 *
198 * @param ipNetworkMask network mask
199 */
200 @Override
201 public void setIpNetworkMask(Ip4Address ipNetworkMask) {
202 this.ipNetworkMask = ipNetworkMask;
203 }
204
205 /**
206 * Adds neighboring router to list.
207 *
208 * @param ospfNbr ospfNbr instance
209 */
210 public void addNeighbouringRouter(OspfNbr ospfNbr) {
211 listOfNeighbors.put(ospfNbr.neighborId().toString(), ospfNbr);
212 }
213
214 /**
215 * Gets the neighbour details from listOfNeighbors map.
216 *
217 * @param neighborId neighbors id
218 * @return ospfNbr neighbor instance
219 */
220 public OspfNbr neighbouringRouter(String neighborId) {
221 return listOfNeighbors.get(neighborId);
222 }
223
sunishvkf7c56552016-07-18 16:02:39 +0530224 /**
225 * Removes all the neighbors.
226 */
227 public void removeNeighbors() {
228 Set<String> neighbors = listOfNeighbors.keySet();
229 for (String neighborId : neighbors) {
230 removeNeighbor(listOfNeighbors.get(neighborId));
231 log.debug("Neighbor removed - {}", neighborId);
232 }
233 listOfNeighbors.clear();
234 }
Kalyankumar Asangi27728f22016-02-17 15:46:28 +0530235
236 /**
sunishvkf7c56552016-07-18 16:02:39 +0530237 * Removes neighbor from the interface neighbor map.
238 *
239 * @param ospfNeighbor OSPF neighbor instance
240 */
241 public void removeNeighbor(OspfNbr ospfNeighbor) {
242 log.debug("Neighbor removed - {}", ospfNeighbor.neighborId());
243 ospfNeighbor.stopInactivityTimeCheck();
244 ospfNeighbor.stopFloodingTimer();
245 ospfNeighbor.stopRxMtDdTimer();
246 ospfNeighbor.stopRxMtLsrTimer();
247
248 listOfNeighbors.remove(ospfNeighbor.neighborId());
249 }
250
251
252 /**
253 * Adds LSA header to map.
Kalyankumar Asangi27728f22016-02-17 15:46:28 +0530254 *
255 * @param lsaHeader LSA header instance
256 */
257 public void addLsaHeaderForDelayAck(LsaHeader lsaHeader) {
258 String key = lsaHeader.lsType() + "-" + lsaHeader.linkStateId() + "-" +
259 lsaHeader.advertisingRouter();
260 if (lsaHeader.lsType() == OspfParameters.LINK_LOCAL_OPAQUE_LSA ||
261 lsaHeader.lsType() == OspfParameters.AREA_LOCAL_OPAQUE_LSA ||
262 lsaHeader.lsType() == OspfParameters.AS_OPAQUE_LSA) {
263 OpaqueLsaHeader header = (OpaqueLsaHeader) lsaHeader;
264 key = lsaHeader.lsType() + "-" + header.opaqueType() + header.opaqueId()
265 + "-" + lsaHeader.advertisingRouter();
266 }
267
268 log.debug("Adding LSA key {} for delayed Ack", key);
269 listOfNeighborMap.put(key, lsaHeader);
270 }
271
272 /**
273 * Removes LSA header from map.
274 *
275 * @param lsaKey key used to store LSA in map
276 */
277 public void removeLsaFromNeighborMap(String lsaKey) {
278 listOfNeighborMap.remove(lsaKey);
279 }
280
281 /**
282 * Checks neighbor is in the list or not.
283 *
284 * @param neighborId neighbors id
285 * @return true if neighbor in list else false
286 */
287 public boolean isNeighborInList(String neighborId) {
288 return listOfNeighbors.containsKey(neighborId);
289 }
290
291 /**
292 * Gets the list of neighbors.
293 *
294 * @return listOfNeighbors as key value pair
295 */
sunishvkf7c56552016-07-18 16:02:39 +0530296 public Map<String, OspfNbr> listOfNeighbors() {
Kalyankumar Asangi27728f22016-02-17 15:46:28 +0530297 return listOfNeighbors;
298 }
299
300 /**
301 * Sets the list of neighbors.
302 *
303 * @param listOfNeighbors as key value pair
304 */
305 public void setListOfNeighbors(HashMap<String, OspfNbr> listOfNeighbors) {
306 this.listOfNeighbors = listOfNeighbors;
307 }
308
309 /**
sunishvkf7c56552016-07-18 16:02:39 +0530310 * Returns interface index.
311 *
312 * @return interface index
313 */
314 public int interfaceIndex() {
315 return interfaceIndex;
316 }
317
318 /**
319 * Set interface index.
320 *
321 * @param interfaceIndex interface index
322 */
323 public void setInterfaceIndex(int interfaceIndex) {
324 this.interfaceIndex = interfaceIndex;
325 }
326
327 /**
Kalyankumar Asangi27728f22016-02-17 15:46:28 +0530328 * Gets the IP address.
329 *
330 * @return IP address
331 */
332 public Ip4Address ipAddress() {
333 return ipAddress;
334 }
335
336 /**
337 * Sets the interface IP address.
338 *
339 * @param ipAddress interface IP address
340 */
341 public void setIpAddress(Ip4Address ipAddress) {
342 this.ipAddress = ipAddress;
343 }
344
345 /**
346 * Gets router priority.
347 *
348 * @return routerPriority value
349 */
350 public int routerPriority() {
351 return routerPriority;
352 }
353
354 /**
355 * Sets router priority.
356 *
357 * @param routerPriority value
358 */
359 public void setRouterPriority(int routerPriority) {
360 this.routerPriority = routerPriority;
361 }
362
363 /**
Kalyankumar Asangi27728f22016-02-17 15:46:28 +0530364 * Gets hello interval time.
365 *
366 * @return hello interval time
367 */
368 public int helloIntervalTime() {
369 return helloIntervalTime;
370 }
371
372 /**
373 * Sets hello interval time.
374 *
375 * @param helloIntervalTime an integer interval time
376 */
377 public void setHelloIntervalTime(int helloIntervalTime) {
378 this.helloIntervalTime = helloIntervalTime;
379 }
380
381 /**
382 * Gets router dead interval time.
383 *
384 * @return router dead interval time
385 */
386 public int routerDeadIntervalTime() {
387 return routerDeadIntervalTime;
388 }
389
390 /**
391 * Sets router dead interval time.
392 *
393 * @param routerDeadIntervalTime router dead interval time
394 */
395 public void setRouterDeadIntervalTime(int routerDeadIntervalTime) {
396 this.routerDeadIntervalTime = routerDeadIntervalTime;
397 }
398
399 /**
400 * Gets interface type.
401 *
402 * @return interfaceType an integer represents interface type
403 */
404 public int interfaceType() {
405 return interfaceType;
406 }
407
408 /**
409 * Sets interface type.
410 *
411 * @param interfaceType interface type
412 */
413 public void setInterfaceType(int interfaceType) {
414 this.interfaceType = interfaceType;
415 }
416
417 /**
Kalyankumar Asangi27728f22016-02-17 15:46:28 +0530418 * Gets max transfer unit.
419 *
420 * @return mtu an integer represents max transfer unit
421 */
422 public int mtu() {
423 return mtu;
424 }
425
426 /**
427 * Sets max transfer unit.
428 *
429 * @param mtu max transfer unit
430 */
431 public void setMtu(int mtu) {
432 this.mtu = mtu;
433 }
434
435 /**
436 * Gets retransmit interval.
437 *
438 * @return retransmit interval
439 */
440 public int reTransmitInterval() {
441 return reTransmitInterval;
442 }
443
444 /**
445 * Sets retransmit interval.
446 *
447 * @param reTransmitInterval retransmit interval
448 */
449 public void setReTransmitInterval(int reTransmitInterval) {
450 this.reTransmitInterval = reTransmitInterval;
451 }
452
453 /**
454 * Gets designated routers IP address.
455 *
456 * @return dr designated routers IP address
457 */
458 public Ip4Address dr() {
459 return dr;
460 }
461
462 /**
463 * Sets designated routers IP address.
464 *
465 * @param dr designated routers IP address
466 */
467 public void setDr(Ip4Address dr) {
468 this.dr = dr;
469 }
470
471 /**
472 * Gets backup designated routers IP address.
473 *
474 * @return bdr backup designated routers IP address
475 */
476 public Ip4Address bdr() {
477 return bdr;
478 }
479
480 /**
481 * Sets backup designated routers IP address.
482 *
483 * @param bdr backup designated routers IP address
484 */
485 public void setBdr(Ip4Address bdr) {
486 this.bdr = bdr;
487 }
488
489 /**
sunishvkf7c56552016-07-18 16:02:39 +0530490 * Represents an interface is up and connected.
Kalyankumar Asangi27728f22016-02-17 15:46:28 +0530491 *
sunishvkf7c56552016-07-18 16:02:39 +0530492 * @throws Exception might throws exception
Kalyankumar Asangi27728f22016-02-17 15:46:28 +0530493 */
sunishvkf7c56552016-07-18 16:02:39 +0530494 public void interfaceUp() throws Exception {
495 log.debug("OSPFInterfaceChannelHandler::interfaceUp...!!!");
496 if (interfaceType() == OspfInterfaceType.POINT_TO_POINT.value()) {
497 setState(OspfInterfaceState.POINT2POINT);
498 interfaceTypeOldValue = interfaceType();
499 log.debug("OSPFInterfaceChannelHandler::InterfaceType {} state {} ",
500 interfaceType(), state());
501 } else if (interfaceType() == OspfInterfaceType.BROADCAST.value()) {
502 //if router priority is 0, move the state to DROther
503 interfaceTypeOldValue = interfaceType();
504 if (routerPriority() == 0) {
505 setState(OspfInterfaceState.DROTHER);
506 } else {
507 log.debug("OSPFInterfaceChannelHandler::InterfaceType {} state {} RouterPriority {}",
508 interfaceType(),
509 state(), routerPriority());
510 setState(OspfInterfaceState.WAITING);
511 //start wait timer - like inactivity timer with router deadInterval
512 startWaitTimer();
513 }
514 }
515 // Start hello timer with interval from config - convert seconds to milliseconds
516 startHelloTimer();
517 ospfArea.refreshArea(this);
518 }
519
520
521 /**
522 * Gets called when a BDR was detected before the wait timer expired.
523 *
524 * @param ch channel instance
525 * @throws Exception might throws exception
526 */
527 public void backupSeen(Channel ch) throws Exception {
528 log.debug("OSPFInterfaceChannelHandler::backupSeen ");
529 if (state() == OspfInterfaceState.WAITING) {
530 electRouter(ch);
531 }
Kalyankumar Asangi27728f22016-02-17 15:46:28 +0530532 }
533
534 /**
sunishvkf7c56552016-07-18 16:02:39 +0530535 * Gets called when no hello message received for particular period.
Kalyankumar Asangi27728f22016-02-17 15:46:28 +0530536 *
sunishvkf7c56552016-07-18 16:02:39 +0530537 * @param ch channel instance
538 * @throws Exception might throws exception
Kalyankumar Asangi27728f22016-02-17 15:46:28 +0530539 */
sunishvkf7c56552016-07-18 16:02:39 +0530540 public void waitTimer(Channel ch) throws Exception {
541 log.debug("OSPFInterfaceChannelHandler::waitTimer ");
542 //According to RFC-2328 section 9.4
543 if (state() == OspfInterfaceState.WAITING) {
544 electRouter(ch);
545 }
Kalyankumar Asangi27728f22016-02-17 15:46:28 +0530546 }
547
sunishvkf7c56552016-07-18 16:02:39 +0530548 /**
549 * Initiates DR election process.
550 *
551 * @param ch netty channel instance
552 * @throws Exception might throws exception
553 */
554 public void callDrElection(Channel ch) throws Exception {
555 log.debug("OSPFInterfaceChannelHandler::callDrElection ");
556 //call when timer expired
557 //no hello message received for particular interval
558 //section 9.4
559 electRouter(ch);
560 interfaceTypeOldValue = interfaceType();
561 }
562
563 /**
564 * Neighbor change event is triggered when the router priority gets changed.
565 *
566 * @throws Exception might throws exception
567 */
568 public void neighborChange() throws Exception {
569 log.debug("OSPFInterfaceChannelHandler::neighborChange ");
570 if (state() == OspfInterfaceState.DR || state() == OspfInterfaceState.BDR ||
571 state() == OspfInterfaceState.DROTHER) {
572 electRouter(channel);
573 }
574 }
575
576 /**
577 * Gets called when an interface is down.
578 * All interface variables are reset, and interface timers disabled.
579 * Also all neighbor connections associated with the interface are destroyed.
580 */
581 public void interfaceDown() {
582 log.debug("OSPFInterfaceChannelHandler::interfaceDown ");
583 stopHelloTimer();
584 listOfNeighbors().clear();
585 setState(OspfInterfaceState.DOWN);
586 }
587
588 /**
589 * When an OSPF message received it is handed over to this method.
590 * Based on the type of the OSPF message received it will be handed over
591 * to corresponding message handler methods.
592 *
593 * @param ospfMessage received OSPF message
594 * @param ctx channel handler context instance.
595 * @throws Exception might throws exception
596 */
597 public void processOspfMessage(OspfMessage ospfMessage, ChannelHandlerContext ctx) throws Exception {
598 log.debug("OspfChannelHandler::processOspfMessage...!!!");
599
600 if (!validateMessage(ospfMessage)) {
601 return;
602 }
603
604 switch (ospfMessage.ospfMessageType().value()) {
605 case OspfParameters.HELLO:
606 processHelloMessage(ospfMessage, ctx);
607 break;
608 case OspfParameters.DD:
609 processDdMessage(ospfMessage, ctx);
610 break;
611 case OspfParameters.LSREQUEST:
612 processLsRequestMessage(ospfMessage, ctx);
613 break;
614 case OspfParameters.LSUPDATE:
615 processLsUpdateMessage(ospfMessage, ctx);
616 break;
617 case OspfParameters.LSACK:
618 processLsAckMessage(ospfMessage, ctx);
619 break;
620 default:
621 log.debug("Unknown packet to process...!!!");
622 break;
623 }
624 }
625
626 /**
627 * Validates the OSPF message received.
628 *
629 * @param ospfMessage OSPF message.
630 * @return true if it is a valid else false.
631 * @throws Exception might throws exception
632 */
633 private boolean validateMessage(OspfMessage ospfMessage) throws Exception {
634 boolean isValid = true;
635 OspfPacketHeader header = (OspfPacketHeader) ospfMessage;
636
637 //added the check to eliminate self origin packets also two interfaces on same router.
638 if (!header.sourceIp().equals(ipAddress()) && !header.routerId().equals(
639 ospfArea.routerId())) {
640 //Verify the checksum
641 ChecksumCalculator checksum = new ChecksumCalculator();
642 if (!checksum.isValidOspfCheckSum(ospfMessage, OspfUtil.OSPFPACKET_CHECKSUM_POS1,
643 OspfUtil.OSPFPACKET_CHECKSUM_POS2)) {
644 log.debug("Checksum mismatch. Received packet type {} ", ospfMessage.ospfMessageType());
645 return false;
646 }
647 if (((OspfPacketHeader) ospfMessage).ospfVersion() != OspfUtil.OSPF_VERSION_2) {
648 log.debug("Received osfpMessage Version should match with Interface Version ");
649 return false;
650 }
651 if (!((OspfPacketHeader) ospfMessage).areaId().equals(ospfArea.areaId())) {
652 log.debug("Received ospf packets are from different area than our Area ID. " +
653 "Received Area ID {}, Our AreaId {} ",
654 ((OspfPacketHeader) ospfMessage).areaId(), ospfArea.areaId());
655 return false;
656 }
657
658 //According to RFC-2328 (8.2)
659 /**
660 * ABR should receive packets from backbone 0.0.0.0 as we are not acting as ABR
661 * we are rejecting the packet.
662 */
663 if (((OspfPacketHeader) ospfMessage).areaId().equals(Ip4Address.valueOf("0.0.0.0"))) {
664 log.debug("ABR should receive packets from backbone 0.0.0.0 as we are not acting as " +
665 "ABR we are rejecting the ospf packet");
666 return false;
667 }
668 if (interfaceType() == OspfInterfaceType.BROADCAST.value() &&
669 !OspfUtil.sameNetwork(((OspfPacketHeader) ospfMessage).sourceIp(),
670 ipAddress(), ipNetworkMask())) {
671 log.debug("Received packets from different subnets. Discarding...!!!");
672 return false;
673 }
674 } else {
675 isValid = false;
676 }
677
678 return isValid;
679 }
680
681 /**
682 * Processes Hello message.
683 *
684 * @param ospfMessage OSPF message instance.
685 * @param ctx context instance.
686 * @throws Exception might throws exception
687 */
688 void processHelloMessage(OspfMessage ospfMessage, ChannelHandlerContext ctx) throws Exception {
689 Channel channel = ctx.getChannel();
690 log.debug("OspfChannelHandler::processHelloMessage...!!!");
691 HelloPacket helloPacket = (HelloPacket) ospfMessage;
692
693 // processing of hello packet as per RFC 2328 section 10.5
694 log.debug("OspfChannelHandler::processHelloMessage::Interface Type {} OSPFInterfaceState {} ",
695 interfaceType(), state());
696
697 if (interfaceType() != OspfInterfaceType.POINT_TO_POINT.value()) {
698 if (!helloPacket.networkMask().equals(ipNetworkMask())) {
699 log.debug("OspfChannelHandler::processHelloMessage::Hello Packet Received does not " +
700 "match the same network mask as the configure Interface");
701 return;
702 }
703 }
704 if (helloPacket.helloInterval() != helloIntervalTime()) {
705 log.debug("OspfChannelHandler::processHelloMessage::Hello Packet Received have the same " +
706 "hello interval as configured Interface");
707 return;
708 }
709 if (helloPacket.routerDeadInterval() != routerDeadIntervalTime()) {
710 log.debug("OspfChannelHandler::processHelloMessage::Hello Packet Received have the same " +
711 "Router Dead interval as configured Interface");
712 return;
713 }
714
715 if (interfaceType == OspfInterfaceType.POINT_TO_POINT.value() &&
716 !helloPacket.dr().equals(OspfUtil.DEFAULTIP)) {
717 log.debug("OspfChannelHandler::processHelloMessage:: Neighbor in broadcast network");
718 return;
719 }
720
721 if (interfaceType == OspfInterfaceType.POINT_TO_POINT.value()) {
722 // to verify if the neighbor which sent the hello is present in the OSPF Interface neighboring list .
723 OspfNbr nbr;
724 if (!isNeighborInList(helloPacket.routerId().toString())) {
725 nbr = new OspfNbrImpl(ospfArea, this, helloPacket.sourceIp(),
726 helloPacket.routerId(), helloPacket.options(), topologyForDeviceAndLink);
727 addNeighbouringRouter(nbr);
728 } else {
729 nbr = neighbouringRouter(helloPacket.routerId().toString());
730 nbr.setRouterPriority(helloPacket.routerPriority());
731 }
732 if (!helloPacket.containsNeighbour(ospfArea.routerId())) {
733 ((OspfNbrImpl) nbr).oneWayReceived(helloPacket, channel);
734 } else {
735 ((OspfNbrImpl) nbr).twoWayReceived(helloPacket, ctx.getChannel());
736 }
737 } else if (interfaceType == OspfInterfaceType.BROADCAST.value()) {
738
739 if (state() == OspfInterfaceState.WAITING) {
740 if ((!helloPacket.dr().equals(Ip4Address.valueOf("0.0.0.0"))) &&
741 (!helloPacket.bdr().equals(Ip4Address.valueOf("0.0.0.0")))) {
742 stopWaitTimer();
743 setDr(helloPacket.dr());
744 setBdr(helloPacket.bdr());
745 if (helloPacket.dr().equals(ipAddress())) {
746 setState(OspfInterfaceState.DR);
747 //refresh router Lsa
748 ospfArea.refreshArea(this);
749 } else if (helloPacket.bdr().equals(ipAddress())) {
750 setState(OspfInterfaceState.BDR);
751 //refresh router Lsa
752 ospfArea.refreshArea(this);
753 } else {
754 setState(OspfInterfaceState.DROTHER);
755 ospfArea.refreshArea(this);
756 }
757
758 } else if (!helloPacket.dr().equals(Ip4Address.valueOf("0.0.0.0")) ||
759 !helloPacket.bdr().equals(Ip4Address.valueOf("0.0.0.0"))) {
760 setDr(helloPacket.dr());
761 setBdr(helloPacket.bdr());
762 }
763 Ip4Address sourceIp = helloPacket.sourceIp();
764 OspfNbr nbr;
765 if (!isNeighborInList(helloPacket.routerId().toString())) {
766 nbr = new OspfNbrImpl(ospfArea, this, sourceIp, helloPacket.routerId(),
767 helloPacket.options(), topologyForDeviceAndLink);
768 nbr.setNeighborId(helloPacket.routerId());
769 nbr.setNeighborBdr(helloPacket.bdr());
770 nbr.setNeighborDr(helloPacket.dr());
771 nbr.setRouterPriority(helloPacket.routerPriority());
772 addNeighbouringRouter(nbr);
773 } else {
774 nbr = neighbouringRouter(helloPacket.routerId().toString());
775 nbr.setRouterPriority(helloPacket.routerPriority());
776 }
777 if (!helloPacket.containsNeighbour(ospfArea.routerId())) {
778 ((OspfNbrImpl) nbr).oneWayReceived(helloPacket, channel);
779 } else {
780 ((OspfNbrImpl) nbr).twoWayReceived(helloPacket, ctx.getChannel());
781 }
782
783 if (helloPacket.dr().equals(sourceIp)) {
784 if (helloPacket.bdr().equals(Ip4Address.valueOf("0.0.0.0"))) {
785 // call backup seen
786 stopWaitTimer();
787 backupSeen(ctx.getChannel());
788 }
789 }
790
791 if (helloPacket.bdr().equals(sourceIp)) {
792 // call backup seen
793 stopWaitTimer();
794 backupSeen(ctx.getChannel());
795 }
796 } else {
797
798 if ((!helloPacket.dr().equals(Ip4Address.valueOf("0.0.0.0")) ||
799 !helloPacket.bdr().equals(Ip4Address.valueOf("0.0.0.0")))
800 && routerPriority() == 0) {
801 setDr(helloPacket.dr());
802 setBdr(helloPacket.bdr());
803 }
804 //To verify if the neighbor which sent the hello is present in the OSPF Interface neighboring list .
805 Ip4Address sourceIp = helloPacket.sourceIp();
806 OspfNbr nbr;
807 if (!isNeighborInList(helloPacket.routerId().toString())) {
808 nbr = new OspfNbrImpl(ospfArea, this, sourceIp, helloPacket.routerId(),
809 helloPacket.options(), topologyForDeviceAndLink);
810 nbr.setNeighborId(helloPacket.routerId());
811 nbr.setNeighborBdr(helloPacket.bdr());
812 nbr.setNeighborDr(helloPacket.dr());
813 nbr.setRouterPriority(helloPacket.routerPriority());
814 addNeighbouringRouter(nbr);
815 ((OspfNbrImpl) nbr).oneWayReceived(helloPacket, channel);
816 } else {
817 log.debug("OspfChannelHandler::NeighborInList::helloPacket.bdr(): {}, " +
818 "helloPacket.dr(): {}", helloPacket.bdr(), helloPacket.dr());
819 nbr = neighbouringRouter(helloPacket.routerId().toString());
820 nbr.setRouterPriority(helloPacket.routerPriority());
821 if (!helloPacket.containsNeighbour(ospfArea.routerId())) {
822 ((OspfNbrImpl) nbr).oneWayReceived(helloPacket, channel);
823 } else {
824 ((OspfNbrImpl) nbr).twoWayReceived(helloPacket, ctx.getChannel());
825 }
826 if (nbr.routerPriority() != helloPacket.routerPriority()) {
827 nbr.setNeighborBdr(helloPacket.bdr());
828 nbr.setNeighborDr(helloPacket.dr());
829 neighborChange();
830 }
831
832
833 if (nbr.neighborIpAddr().equals(helloPacket.dr()) &&
834 !(nbr.neighborIpAddr().equals(nbr.neighborDr()))) {
835 nbr.setNeighborBdr(helloPacket.bdr());
836 nbr.setNeighborDr(helloPacket.dr());
837 neighborChange();
838 }
839
840 if (!(nbr.neighborIpAddr().equals(helloPacket.dr())) &&
841 (nbr.neighborIpAddr().equals(nbr.neighborDr()))) {
842 nbr.setNeighborBdr(helloPacket.bdr());
843 nbr.setNeighborDr(helloPacket.dr());
844 neighborChange();
845 }
846
847 if (nbr.neighborIpAddr().equals(helloPacket.bdr()) &&
848 !(nbr.neighborIpAddr().equals(nbr.neighborBdr()))) {
849 nbr.setNeighborBdr(helloPacket.bdr());
850 nbr.setNeighborDr(helloPacket.dr());
851 neighborChange();
852 }
853
854 if (!(nbr.neighborIpAddr().equals(helloPacket.bdr())) &&
855 (nbr.neighborIpAddr().equals(nbr.neighborBdr()))) {
856 nbr.setNeighborBdr(helloPacket.bdr());
857 nbr.setNeighborDr(helloPacket.dr());
858 neighborChange();
859 }
860
861 nbr.setNeighborBdr(helloPacket.bdr());
862 nbr.setNeighborDr(helloPacket.dr());
863 }
864 }
865 }
866 }
867
868 /**
869 * process the DD message which received.
870 *
871 * @param ospfMessage OSPF message instance.
872 * @param ctx channel handler context instance
873 * @throws Exception might throws exception
874 */
875 void processDdMessage(OspfMessage ospfMessage, ChannelHandlerContext ctx) throws Exception {
876 log.debug("OspfChannelHandler::processDdMessage...!!!");
877 Channel channel = ctx.getChannel();
878 DdPacket ddPacket = (DdPacket) ospfMessage;
879 log.debug("Got DD packet from {}", ddPacket.sourceIp());
880 //check it is present in listOfNeighbors
881 Ip4Address neighbourId = ddPacket.routerId();
882 OspfNbr nbr = neighbouringRouter(neighbourId.toString());
883
884 if (nbr != null) {
885 log.debug("OspfChannelHandler::processDdMessage:: OSPFNeighborState {}", nbr.getState());
886 // set options for the NBR
887 nbr.setIsOpaqueCapable(ddPacket.isOpaqueCapable());
888 if (ddPacket.imtu() > mtu()) {
889 log.debug("the MTU size is greater than the interface MTU");
890 return;
891 }
892 if (nbr.getState() == OspfNeighborState.DOWN) {
893 return;
894 }
895 if (nbr.getState() == OspfNeighborState.ATTEMPT) {
896 return;
897 }
898 if (nbr.getState() == OspfNeighborState.TWOWAY) {
899 nbr.adjOk(channel);
900 return;
901 }
902 //if init is the state call twoWayReceived
903 if (nbr.getState() == OspfNeighborState.INIT) {
904 ((OspfNbrImpl) nbr).twoWayReceived(ddPacket, ctx.getChannel());
905 } else if (nbr.getState() == OspfNeighborState.EXSTART) {
906 //get I,M,MS Bits
907 int initialize = ddPacket.isInitialize();
908 int more = ddPacket.isMore();
909 int masterOrSlave = ddPacket.isMaster();
910 int options = ddPacket.options();
911 nbr.setOptions(options);
912
913 if (initialize == OspfUtil.INITIALIZE_SET && more == OspfUtil.MORE_SET &&
914 masterOrSlave == OspfUtil.IS_MASTER) {
915 if (ddPacket.getLsaHeaderList().isEmpty()) {
916 if (OspfUtil.ipAddressToLong(ddPacket.routerId().toString()) >
917 OspfUtil.ipAddressToLong(ospfArea.routerId().toString())) {
918 nbr.setIsMaster(OspfUtil.IS_MASTER);
919 ((OspfNbrImpl) nbr).setLastDdPacket(ddPacket);
920 nbr.setDdSeqNum(ddPacket.sequenceNo());
921 nbr.setOptions(ddPacket.options());
922 ((OspfNbrImpl) nbr).negotiationDone(ddPacket, true, ddPacket.getLsaHeaderList(),
923 ctx.getChannel());
924 }
925 }
926 }
927 if (initialize == OspfUtil.INITIALIZE_NOTSET && masterOrSlave == OspfUtil.NOT_MASTER) {
928 if (nbr.ddSeqNum() == ddPacket.sequenceNo()) {
929 if (OspfUtil.ipAddressToLong(ddPacket.routerId().toString()) <
930 OspfUtil.ipAddressToLong(ospfArea.routerId().toString())) {
931 ((OspfNbrImpl) nbr).setLastDdPacket(ddPacket);
932 nbr.setOptions(ddPacket.options());
933 nbr.setDdSeqNum(nbr.ddSeqNum() + 1);
934 ((OspfNbrImpl) nbr).negotiationDone(ddPacket, false, ddPacket.getLsaHeaderList(),
935 ctx.getChannel());
936 }
937 }
938 }
939
940 } else if (nbr.getState() == OspfNeighborState.EXCHANGE) {
941 //get I,M,MS Bits
942 log.debug("Neighbor state:: EXCHANGE");
943 boolean isDuplicateDDPacket = compareDdPackets(ddPacket, ((OspfNbrImpl) nbr).lastDdPacket());
944 int initialize = ddPacket.isInitialize();
945 int more = ddPacket.isMore();
946 int masterOrSlave = ddPacket.isMaster();
947 int options = ddPacket.options();
948
949 if (!isDuplicateDDPacket) {
950 //if dd packet is not duplicate then continue
951 if (nbr.isMaster() != masterOrSlave) {
952 DdPacket newResPacket =
953 (DdPacket) ((OspfNbrImpl) nbr).seqNumMismatch("Master/Slave Inconsistency");
954 newResPacket.setDestinationIp(ddPacket.sourceIp());
955 log.debug("Sending back DDPacket to {}", ddPacket.sourceIp());
956 byte[] messageToWrite = getMessage(newResPacket);
957 ctx.getChannel().write(messageToWrite);
958 } else if (initialize == 1) {
959 DdPacket newResPacket =
960 (DdPacket) ((OspfNbrImpl) nbr).seqNumMismatch("Initialize bit inconsistency");
961 newResPacket.setDestinationIp(ddPacket.sourceIp());
962 log.debug("Sending back DDPacket to {}", ddPacket.sourceIp());
963 byte[] messageToWrite = getMessage(newResPacket);
964 ctx.getChannel().write(messageToWrite);
965 } else {
966
967 if (masterOrSlave == OspfUtil.NOT_MASTER) {
968 if (ddPacket.sequenceNo() == nbr.ddSeqNum()) {
969 //Process the DD Packet
970 ((OspfNbrImpl) nbr).processDdPacket(false, ddPacket, ctx.getChannel());
971 log.debug("Received DD Packet");
972 } else {
973 DdPacket newResPacket =
974 (DdPacket) ((OspfNbrImpl) nbr).seqNumMismatch("Sequence Number Mismatch");
975 newResPacket.setDestinationIp(ddPacket.sourceIp());
976 log.debug("Sending back DDPacket to {}", ddPacket.sourceIp());
977 byte[] messageToWrite = getMessage(newResPacket);
978 ctx.getChannel().write(messageToWrite);
979 }
980 } else {
981 //we are the slave
982 if (ddPacket.sequenceNo() == (nbr.ddSeqNum() + 1)) {
983 ((OspfNbrImpl) nbr).setLastDdPacket(ddPacket);
984 ((OspfNbrImpl) nbr).processDdPacket(true, ddPacket, ctx.getChannel());
985 log.debug("Process DD Packet");
986 } else {
987 DdPacket newResPacket =
988 (DdPacket) ((OspfNbrImpl) nbr).seqNumMismatch("options inconsistency");
989 newResPacket.setDestinationIp(ddPacket.sourceIp());
990 log.debug("Sending back DDPacket to {}", ddPacket.sourceIp());
991 byte[] messageToWrite = getMessage(newResPacket);
992 ctx.getChannel().write(messageToWrite);
993 }
994 }
995 }
996 } else {
997 if (masterOrSlave == OspfUtil.NOT_MASTER) {
998 return;
999 } else {
1000 DdPacket newResPacket = ((OspfNbrImpl) nbr).lastSentDdPacket();
1001 log.debug("Sending back DDPacket to {}", ddPacket.sourceIp());
1002 byte[] messageToWrite = getMessage(newResPacket);
1003 ctx.getChannel().write(messageToWrite);
1004 }
1005 }
1006 } else if (nbr.getState() == OspfNeighborState.LOADING || nbr.getState() == OspfNeighborState.FULL) {
1007 //In case if we are slave then we have to send the last received DD Packet
1008 int options = ddPacket.options();
1009 if (nbr.options() != options) {
1010 OspfMessage newResPacket = ((OspfNbrImpl) nbr).seqNumMismatch("Initialize bit inconsistency");
1011 newResPacket.setDestinationIp(ddPacket.sourceIp());
1012 byte[] messageToWrite = getMessage(newResPacket);
1013 ctx.getChannel().write(messageToWrite);
1014 } else if (ddPacket.isInitialize() == OspfUtil.INITIALIZE_SET) {
1015 OspfMessage newResPacket = ((OspfNbrImpl) nbr).seqNumMismatch("Initialize bit inconsistency");
1016 newResPacket.setDestinationIp(ddPacket.sourceIp());
1017 byte[] messageToWrite = getMessage(newResPacket);
1018 ctx.getChannel().write(messageToWrite);
1019 }
1020 boolean isDuplicate = compareDdPackets(ddPacket, ((OspfNbrImpl) nbr).lastDdPacket());
1021 //we are master
1022 if (nbr.isMaster() != OspfUtil.IS_MASTER) {
1023 // check if the packet is duplicate, duplicates should be discarded by the master
1024 if (isDuplicate) {
1025 log.debug("received a duplicate DD packet");
1026 }
1027 } else {
1028 //The slave must respond to duplicates by repeating the last Database Description packet
1029 //that it had sent.
1030 if (isDuplicate) {
1031 ddPacket.setDestinationIp(ddPacket.sourceIp());
1032 byte[] messageToWrite = getMessage(((OspfNbrImpl) nbr).lastSentDdPacket());
1033 ctx.getChannel().write(messageToWrite);
1034 log.debug("Sending back the duplicate packet ");
1035 }
1036 }
1037 }
1038 }
1039 }
1040
1041 /**
1042 * Process the Ls Request message.
1043 *
1044 * @param ospfMessage OSPF message instance.
1045 * @param ctx channel handler context instance.
1046 * @throws Exception might throws exception
1047 */
1048 void processLsRequestMessage(OspfMessage ospfMessage, ChannelHandlerContext ctx) throws Exception {
1049 log.debug("OspfChannelHandler::processLsRequestMessage...!!!");
1050 Channel channel = ctx.getChannel();
1051 LsRequest lsrPacket = (LsRequest) ospfMessage;
1052 OspfNbr nbr = neighbouringRouter(lsrPacket.routerId().toString());
1053
1054 if (nbr.getState() == OspfNeighborState.EXCHANGE || nbr.getState() == OspfNeighborState.LOADING ||
1055 nbr.getState() == OspfNeighborState.FULL) {
1056
1057 LsRequest reqMsg = (LsRequest) ospfMessage;
1058 if (reqMsg.getLinkStateRequests().isEmpty()) {
1059 log.debug("Received Link State Request Vector is Empty ");
1060 return;
1061 } else {
1062 //Send the LsUpdate back
1063 ListIterator<LsRequestPacket> listItr = reqMsg.getLinkStateRequests().listIterator();
1064 while (listItr.hasNext()) {
1065 LsUpdate lsupdate = new LsUpdate();
1066 lsupdate.setOspfVer(OspfUtil.OSPF_VERSION);
1067 lsupdate.setOspftype(OspfPacketType.LSUPDATE.value());
1068 lsupdate.setRouterId(ospfArea.routerId());
1069 lsupdate.setAreaId(ospfArea.areaId());
1070 lsupdate.setAuthType(OspfUtil.NOT_ASSIGNED);
1071 lsupdate.setAuthentication(OspfUtil.NOT_ASSIGNED);
1072 lsupdate.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
1073 lsupdate.setChecksum(OspfUtil.NOT_ASSIGNED);
1074
1075 //limit to mtu
1076 int currentLength = OspfUtil.OSPF_HEADER_LENGTH + OspfUtil.FOUR_BYTES;
1077 int maxSize = mtu() -
1078 OspfUtil.LSA_HEADER_LENGTH; // subtract a normal IP header.
1079 int noLsa = 0;
1080 while (listItr.hasNext()) {
1081 LsRequestPacket lsRequest = (LsRequestPacket) listItr.next();
1082 // to verify length of the LSA
1083 LsaWrapper wrapper = ospfArea.getLsa(lsRequest.lsType(), lsRequest.linkStateId(),
1084 lsRequest.ownRouterId());
1085 OspfLsa ospflsa = wrapper.ospfLsa();
1086 if ((currentLength + ((LsaWrapperImpl) wrapper).lsaHeader().lsPacketLen()) >= maxSize) {
1087 listItr.previous();
1088 break;
1089 }
1090 if (ospflsa != null) {
1091 lsupdate.addLsa(ospflsa);
1092 noLsa++;
1093
1094 currentLength = currentLength + ((LsaWrapperImpl) wrapper).lsaHeader().lsPacketLen();
1095 } else {
1096 nbr.badLSReq(channel);
1097 }
1098 }
1099 lsupdate.setNumberOfLsa(noLsa);
1100 //set the destination
1101 if (state() == OspfInterfaceState.DR ||
1102 state() == OspfInterfaceState.BDR ||
1103 state() == OspfInterfaceState.POINT2POINT) {
1104 lsupdate.setDestinationIp(OspfUtil.ALL_SPF_ROUTERS);
1105 } else if (state() == OspfInterfaceState.DROTHER) {
1106 lsupdate.setDestinationIp(OspfUtil.ALL_DROUTERS);
1107 }
1108 byte[] messageToWrite = getMessage(lsupdate);
1109 ctx.getChannel().write(messageToWrite);
1110 }
1111 }
1112 }
1113 }
1114
1115 /**
1116 * Process the ls update message.
1117 *
1118 * @param ospfMessage OSPF message instance.
1119 * @param ctx channel handler context instance.
1120 * @throws Exception might throws exception
1121 */
1122 void processLsUpdateMessage(OspfMessage ospfMessage, ChannelHandlerContext ctx) throws Exception {
1123 log.debug("OspfChannelHandler::processLsUpdateMessage");
1124 LsUpdate lsUpdate = (LsUpdate) ospfMessage;
1125 String neighbourId = lsUpdate.routerId().toString();
1126 //LSUpdate packet has been associated with a particular neighbor.
1127 //Neighbor should not be in lesser state than Exchange.
1128 if (isNeighborInList(neighbourId)) {
1129 OspfNbrImpl nbr = (OspfNbrImpl) neighbouringRouter(neighbourId);
1130 if (nbr.getState() == OspfNeighborState.EXCHANGE ||
1131 nbr.getState() == OspfNeighborState.LOADING) {
1132 nbr.processLsUpdate(lsUpdate, ctx.getChannel());
1133 } else if (nbr.getState() == OspfNeighborState.FULL) {
1134 if (lsUpdate.noLsa() != 0) {
1135 List<OspfLsa> list = lsUpdate.getLsaList();
1136 Iterator itr = list.iterator();
1137 while (itr.hasNext()) {
1138 LsaHeader lsa = (LsaHeader) itr.next();
1139 nbr.processReceivedLsa(lsa, true, ctx.getChannel(), lsUpdate.sourceIp());
1140 }
1141 } else {
1142 return;
1143 }
1144 }
1145 }
1146 }
1147
1148 /**
1149 * Process the ls acknowledge message.
1150 *
1151 * @param ospfMessage OSPF message instance.
1152 * @param ctx channel handler context instance.
1153 * @throws Exception might throws exception
1154 */
1155 void processLsAckMessage(OspfMessage ospfMessage, ChannelHandlerContext ctx) throws Exception {
1156 log.debug("OspfChannelHandler::processLsAckMessage");
1157 LsAcknowledge lsAckPacket = (LsAcknowledge) ospfMessage;
1158 //check it is present in listOfNeighbors
1159 OspfNbrImpl nbr = (OspfNbrImpl) neighbouringRouter(lsAckPacket.routerId().toString());
1160 if (nbr != null) {
1161 if (nbr.getState().getValue() < OspfNeighborState.EXCHANGE.getValue()) {
1162 // discard the packet.
1163 return;
1164 } else {
1165 // process ls acknowledgements
1166 Iterator itr = lsAckPacket.getLinkStateHeaders().iterator();
1167 while (itr.hasNext()) {
1168 LsaHeader lsRequest = (LsaHeader) itr.next();
1169
1170 OspfLsa ospfLsa =
1171 (OspfLsa) nbr.getPendingReTxList().get(((OspfAreaImpl) ospfArea).getLsaKey(lsRequest));
Palash Kalaa2625f72017-04-11 17:31:32 +09001172 if (ospfLsa != null) {
sunishvkf7c56552016-07-18 16:02:39 +05301173 String isSame = ((OspfLsdbImpl) ospfArea.database()).isNewerOrSameLsa(
1174 lsRequest, (LsaHeader) ospfLsa);
1175 if (isSame.equals("same")) {
1176 nbr.getPendingReTxList().remove(((OspfAreaImpl) ospfArea).getLsaKey(lsRequest));
1177 }
1178 }
1179 }
1180 }
1181 }
1182 }
1183
1184 /**
1185 * Compares two Dd Packets to check whether its duplicate or not.
1186 *
1187 * @param receivedDPacket received DD packet from network.
1188 * @param lastDdPacket Last DdPacket which we sent.
1189 * @return true if it is a duplicate packet else false.
1190 */
1191 public boolean compareDdPackets(DdPacket receivedDPacket, DdPacket lastDdPacket) {
1192 if (receivedDPacket.isInitialize() == lastDdPacket.isInitialize()) {
1193 if (receivedDPacket.isMaster() == lastDdPacket.isMaster()) {
1194 if (receivedDPacket.isMore() == lastDdPacket.isMore()) {
1195 if (receivedDPacket.options() == lastDdPacket.options()) {
1196 if (receivedDPacket.sequenceNo() == lastDdPacket.sequenceNo()) {
1197 return true;
1198 }
1199 }
1200 }
1201 }
1202 }
1203 return false;
1204 }
1205
1206 /**
1207 * Starts the hello timer which sends hello packet every configured seconds.
1208 */
1209 public void startHelloTimer() {
1210 log.debug("OSPFInterfaceChannelHandler::startHelloTimer");
1211 exServiceHello = Executors.newSingleThreadScheduledExecutor();
1212 helloTimerTask = new InternalHelloTimer();
1213 final ScheduledFuture<?> helloHandle =
1214 exServiceHello.scheduleAtFixedRate(helloTimerTask, delay, helloIntervalTime, TimeUnit.SECONDS);
1215 }
1216
1217 /**
1218 * Stops the hello timer.
1219 */
1220 public void stopHelloTimer() {
1221 log.debug("OSPFInterfaceChannelHandler::stopHelloTimer ");
1222 exServiceHello.shutdown();
1223 }
1224
1225 /**
1226 * Starts the wait timer.
1227 */
1228 public void startWaitTimer() {
1229 log.debug("OSPFNbr::startWaitTimer");
1230 exServiceWait = Executors.newSingleThreadScheduledExecutor();
1231 waitTimerTask = new InternalWaitTimer();
1232 final ScheduledFuture<?> waitTimerHandle =
1233 exServiceWait.schedule(waitTimerTask, routerDeadIntervalTime(), TimeUnit.SECONDS);
1234 }
1235
1236 /**
1237 * Stops the wait timer.
1238 */
1239 public void stopWaitTimer() {
1240 log.debug("OSPFNbr::stopWaitTimer ");
1241 exServiceWait.shutdown();
1242 }
1243
1244 /**
1245 * Starts the timer which waits for configured seconds and sends Delayed Ack Packet.
1246 */
1247 public void startDelayedAckTimer() {
1248 if (!isDelayedAckTimerScheduled) {
1249 log.debug("Started DelayedAckTimer...!!!");
1250 exServiceDelayedAck = Executors.newSingleThreadScheduledExecutor();
1251 delayedAckTimerTask = new InternalDelayedAckTimer();
1252 final ScheduledFuture<?> delayAckHandle =
1253 exServiceDelayedAck.scheduleAtFixedRate(delayedAckTimerTask, delayedAckTimerInterval,
1254 delayedAckTimerInterval, TimeUnit.MILLISECONDS);
1255 isDelayedAckTimerScheduled = true;
1256 }
1257 }
1258
1259 /**
1260 * Stops the delayed acknowledge timer.
1261 */
1262 public void stopDelayedAckTimer() {
1263 if (isDelayedAckTimerScheduled) {
1264 log.debug("Stopped DelayedAckTimer...!!!");
1265 isDelayedAckTimerScheduled = false;
1266 exServiceDelayedAck.shutdown();
1267 }
1268 }
1269
1270 /**
1271 * Performs DR election.
1272 *
1273 * @param ch Netty Channel instance.
1274 * @throws Exception might throws exception
1275 */
1276 public void electRouter(Channel ch) throws Exception {
1277
1278 Ip4Address currentDr = dr();
1279 Ip4Address currentBdr = bdr();
1280 OspfInterfaceState oldState = state();
1281 OspfInterfaceState newState;
1282
1283 log.debug("OSPFInterfaceChannelHandler::electRouter -> currentDr: {}, currentBdr: {}",
1284 currentDr, currentBdr);
1285 List<OspfEligibleRouter> eligibleRouters = calculateListOfEligibleRouters(new OspfEligibleRouter());
1286
1287 log.debug("OSPFInterfaceChannelHandler::electRouter -> eligibleRouters: {}", eligibleRouters);
1288 OspfEligibleRouter electedBdr = electBdr(eligibleRouters);
1289 OspfEligibleRouter electedDr = electDr(eligibleRouters, electedBdr);
1290
1291 setBdr(electedBdr.getIpAddress());
1292 setDr(electedDr.getIpAddress());
1293
1294 if (electedBdr.getIpAddress().equals(ipAddress()) &&
1295 !electedBdr.getIpAddress().equals(currentBdr)) {
1296 setState(OspfInterfaceState.BDR);
1297 }
1298
1299 if (electedDr.getIpAddress().equals(ipAddress()) &&
1300 !electedDr.getIpAddress().equals(currentDr)) {
1301 setState(OspfInterfaceState.DR);
1302 }
1303
1304 if (state() != oldState &&
1305 !(state() == OspfInterfaceState.DROTHER &&
1306 oldState.value() < OspfInterfaceState.DROTHER.value())) {
1307 log.debug("Recalculating as the State is changed ");
1308 log.debug("OSPFInterfaceChannelHandler::electRouter -> currentDr: {}, currentBdr: {}",
1309 currentDr, currentBdr);
1310 eligibleRouters = calculateListOfEligibleRouters(new OspfEligibleRouter());
1311
1312 log.debug("OSPFInterfaceChannelHandler::electRouter -> eligibleRouters: {}", eligibleRouters);
1313 electedBdr = electBdr(eligibleRouters);
1314 electedDr = electDr(eligibleRouters, electedBdr);
1315
1316 setBdr(electedBdr.getIpAddress());
1317 setDr(electedDr.getIpAddress());
1318 }
1319
1320 if (electedBdr.getIpAddress().equals(ipAddress()) &&
1321 !electedBdr.getIpAddress().equals(currentBdr)) {
1322 setState(OspfInterfaceState.BDR);
1323 ospfArea.refreshArea(this);
1324 }
1325
1326 if (electedDr.getIpAddress().equals(ipAddress()) &&
1327 !electedDr.getIpAddress().equals(currentDr)) {
1328 setState(OspfInterfaceState.DR);
1329 //Refresh Router Lsa & Network Lsa
1330 ospfArea.refreshArea(this);
1331 }
1332
1333 if (currentDr != electedDr.getIpAddress() || currentBdr != electedBdr.getIpAddress()) {
1334 Set<String> negibhorIdList;
1335 negibhorIdList = listOfNeighbors().keySet();
1336 for (String routerid : negibhorIdList) {
1337 OspfNbrImpl nbr = (OspfNbrImpl) neighbouringRouter(routerid);
1338 if (nbr.getState().getValue() >= OspfNeighborState.TWOWAY.getValue()) {
1339 nbr.adjOk(ch);
1340 }
1341 }
1342 }
1343
1344 log.debug("OSPFInterfaceChannelHandler::electRouter -> ElectedDR: {}, ElectedBDR: {}",
1345 electedDr.getIpAddress(), electedBdr.getIpAddress());
1346 }
1347
1348
1349 /**
1350 * BDR Election process. Find the list of eligible router to participate in the process.
1351 *
1352 * @param electedDr router elected as DR.
1353 * @return list of eligible routers
1354 */
1355 public List<OspfEligibleRouter> calculateListOfEligibleRouters(OspfEligibleRouter electedDr) {
1356 log.debug("OSPFNbr::calculateListOfEligibleRouters ");
1357 Set<String> neighborIdList;
1358 List<OspfEligibleRouter> eligibleRouters = new ArrayList<>();
1359
1360 neighborIdList = listOfNeighbors().keySet();
1361 for (String routerId : neighborIdList) {
1362 OspfNbrImpl nbr = (OspfNbrImpl) neighbouringRouter(routerId);
1363 if (nbr.getState().getValue() >= OspfNeighborState.TWOWAY.getValue() &&
1364 nbr.routerPriority() > 0) {
1365 OspfEligibleRouter router = new OspfEligibleRouter();
1366 router.setIpAddress(nbr.neighborIpAddr());
1367 router.setRouterId(nbr.neighborId());
1368 router.setRouterPriority(nbr.routerPriority());
1369 if (nbr.neighborDr().equals(nbr.neighborIpAddr()) ||
1370 electedDr.getIpAddress().equals(nbr.neighborIpAddr())) {
1371 router.setIsDr(true);
1372 } else if (nbr.neighborBdr().equals(nbr.neighborIpAddr())) {
1373 router.setIsBdr(true);
1374 }
1375 eligibleRouters.add(router);
1376 }
1377 }
1378 // interface does not have states like two and all
1379 if (routerPriority() > 0) {
1380 OspfEligibleRouter router = new OspfEligibleRouter();
1381 router.setIpAddress(ipAddress());
1382 router.setRouterId(ospfArea.routerId());
1383 router.setRouterPriority(routerPriority());
1384 if (dr().equals(ipAddress()) ||
1385 electedDr.getIpAddress().equals(ipAddress())) {
1386 router.setIsDr(true);
1387 } else if (bdr().equals(ipAddress()) &&
1388 !dr().equals(ipAddress())) {
1389 router.setIsBdr(true);
1390 }
1391
1392 eligibleRouters.add(router);
1393 }
1394
1395 return eligibleRouters;
1396 }
1397
1398 /**
1399 * Based on router priority assigns BDR.
1400 *
1401 * @param eligibleRouters list of routers to participate in bdr election.
1402 * @return OSPF Eligible router instance.
1403 */
1404 public OspfEligibleRouter electBdr(List<OspfEligibleRouter> eligibleRouters) {
1405 log.debug("OSPFInterfaceChannelHandler::electBdr -> eligibleRouters: {}", eligibleRouters);
1406 List<OspfEligibleRouter> declaredAsBdr = new ArrayList<>();
1407 List<OspfEligibleRouter> notDrAndBdr = new ArrayList<>();
1408 for (OspfEligibleRouter router : eligibleRouters) {
1409 if (router.isBdr()) {
1410 declaredAsBdr.add(router);
1411 }
1412 if (!router.isBdr() && !router.isDr()) {
1413 notDrAndBdr.add(router);
1414 }
1415 }
1416
1417 OspfEligibleRouter electedBdr = new OspfEligibleRouter();
1418 if (!declaredAsBdr.isEmpty()) {
1419 if (declaredAsBdr.size() == 1) {
1420 electedBdr = declaredAsBdr.get(0);
1421 } else if (declaredAsBdr.size() > 1) {
1422 electedBdr = selectRouterBasedOnPriority(declaredAsBdr);
1423 }
1424 } else {
1425 if (notDrAndBdr.size() == 1) {
1426 electedBdr = notDrAndBdr.get(0);
1427 } else if (notDrAndBdr.size() > 1) {
1428 electedBdr = selectRouterBasedOnPriority(notDrAndBdr);
1429 }
1430 }
1431
1432 electedBdr.setIsBdr(true);
1433 electedBdr.setIsDr(false);
1434
1435 return electedBdr;
1436 }
1437
1438 /**
1439 * DR Election process.
1440 *
1441 * @param eligibleRouters list of eligible routers.
1442 * @param electedBdr Elected Bdr, OSPF eligible router instance.
1443 * @return OSPF eligible router instance.
1444 */
1445 public OspfEligibleRouter electDr(List<OspfEligibleRouter> eligibleRouters,
1446 OspfEligibleRouter electedBdr) {
1447
1448 List<OspfEligibleRouter> declaredAsDr = new ArrayList<>();
1449 for (OspfEligibleRouter router : eligibleRouters) {
1450 if (router.isDr()) {
1451 declaredAsDr.add(router);
1452 }
1453 }
1454
1455 OspfEligibleRouter electedDr = new OspfEligibleRouter();
1456 if (!declaredAsDr.isEmpty()) {
1457 if (declaredAsDr.size() == 1) {
1458 electedDr = declaredAsDr.get(0);
1459 } else if (eligibleRouters.size() > 1) {
1460 electedDr = selectRouterBasedOnPriority(declaredAsDr);
1461 }
1462 } else {
1463 electedDr = electedBdr;
1464 electedDr.setIsDr(true);
1465 electedDr.setIsBdr(false);
1466 }
1467
1468 return electedDr;
1469 }
1470
1471 /**
1472 * DR election process.
1473 *
1474 * @param routersList list of eligible routers.
1475 * @return OSPF eligible router instance.
1476 */
1477 public OspfEligibleRouter selectRouterBasedOnPriority(List<OspfEligibleRouter> routersList) {
1478
1479 OspfEligibleRouter initialRouter = routersList.get(0);
1480
1481 for (int i = 1; i < routersList.size(); i++) {
1482 OspfEligibleRouter router = routersList.get(i);
1483 if (router.getRouterPriority() > initialRouter.getRouterPriority()) {
1484 initialRouter = router;
1485 } else if (router.getRouterPriority() == initialRouter.getRouterPriority()) {
1486 try {
1487 if (OspfUtil.ipAddressToLong(router.getIpAddress().toString()) >
1488 OspfUtil.ipAddressToLong(initialRouter.getIpAddress().toString())) {
1489 initialRouter = router;
1490 }
1491 } catch (Exception e) {
1492 log.debug("OSPFInterfaceChannelHandler::selectRouterBasedOnPriority ->" +
1493 " eligibleRouters: {}", initialRouter);
1494 }
1495 }
1496 }
1497
1498 return initialRouter;
1499 }
1500
1501 /**
1502 * Adds device information.
1503 *
1504 * @param ospfRouter OSPF router instance
1505 */
1506 public void addDeviceInformation(OspfRouter ospfRouter) {
1507 controller.addDeviceDetails(ospfRouter);
1508 }
1509
1510 /**
1511 * removes device information.
1512 *
1513 * @param ospfRouter OSPF neighbor instance
1514 */
1515 public void removeDeviceInformation(OspfRouter ospfRouter) {
1516 controller.removeDeviceDetails(ospfRouter);
1517 }
1518
1519 /**
1520 * Adds link information.
1521 *
1522 * @param ospfRouter OSPF router instance
1523 * @param ospfLinkTed list link ted instances
1524 */
1525 public void addLinkInformation(OspfRouter ospfRouter, OspfLinkTed ospfLinkTed) {
1526 controller.addLinkDetails(ospfRouter, ospfLinkTed);
1527 }
1528
1529 /**
1530 * Removes link information.
1531 *
1532 * @param ospfRouter OSPF router instance
1533 * @param ospfLinkTed OSPF link TED instance
1534 */
1535 public void removeLinkInformation(OspfRouter ospfRouter, OspfLinkTed ospfLinkTed) {
1536 controller.removeLinkDetails(ospfRouter, ospfLinkTed);
1537 }
1538
1539 /**
1540 * Gets message as bytes.
1541 *
1542 * @param ospfMessage OSPF message
1543 * @return OSPF message
1544 */
1545 private byte[] getMessage(OspfMessage ospfMessage) {
1546 OspfMessageWriter messageWriter = new OspfMessageWriter();
1547 if (state().equals(OspfInterfaceState.POINT2POINT)) {
1548 ospfMessage.setDestinationIp(OspfUtil.ALL_SPF_ROUTERS);
1549 }
1550 return (messageWriter.getMessage(ospfMessage, interfaceIndex, state.value()));
1551 }
1552
1553
Kalyankumar Asangi27728f22016-02-17 15:46:28 +05301554 @Override
1555 public boolean equals(Object o) {
1556 if (this == o) {
1557 return true;
1558 }
1559 if (o == null || getClass() != o.getClass()) {
1560 return false;
1561 }
1562 OspfInterfaceImpl that = (OspfInterfaceImpl) o;
sunishvkf7c56552016-07-18 16:02:39 +05301563 return Objects.equal(helloIntervalTime, that.helloIntervalTime) &&
Kalyankumar Asangi27728f22016-02-17 15:46:28 +05301564 Objects.equal(routerDeadIntervalTime, that.routerDeadIntervalTime) &&
Kalyankumar Asangi27728f22016-02-17 15:46:28 +05301565 Objects.equal(routerPriority, that.routerPriority) &&
Kalyankumar Asangi27728f22016-02-17 15:46:28 +05301566 Objects.equal(interfaceType, that.interfaceType) &&
Kalyankumar Asangi27728f22016-02-17 15:46:28 +05301567 Objects.equal(mtu, that.mtu) &&
1568 Objects.equal(reTransmitInterval, that.reTransmitInterval) &&
1569 Objects.equal(ipAddress, that.ipAddress) &&
1570 Objects.equal(ipNetworkMask, that.ipNetworkMask) &&
1571 Objects.equal(listOfNeighbors, that.listOfNeighbors) &&
Kalyankumar Asangi27728f22016-02-17 15:46:28 +05301572 Objects.equal(dr, that.dr) &&
1573 Objects.equal(bdr, that.bdr);
1574 }
1575
1576 @Override
1577 public int hashCode() {
sunishvkf7c56552016-07-18 16:02:39 +05301578 return Objects.hashCode(ipAddress, ipNetworkMask, helloIntervalTime,
1579 routerDeadIntervalTime, routerPriority, listOfNeighbors,
1580 interfaceType, mtu, reTransmitInterval, dr, bdr);
Kalyankumar Asangi27728f22016-02-17 15:46:28 +05301581 }
1582
1583 @Override
1584 public String toString() {
1585 return MoreObjects.toStringHelper(getClass())
1586 .omitNullValues()
1587 .add("ipAddress", ipAddress)
1588 .add("routerPriority", routerPriority)
Kalyankumar Asangi27728f22016-02-17 15:46:28 +05301589 .add("helloIntervalTime", helloIntervalTime)
1590 .add("routerDeadIntervalTime", routerDeadIntervalTime)
1591 .add("interfaceType", interfaceType)
Kalyankumar Asangi27728f22016-02-17 15:46:28 +05301592 .add("mtu", mtu)
1593 .add("reTransmitInterval", reTransmitInterval)
1594 .add("dr", dr)
1595 .add("bdr", bdr)
Kalyankumar Asangi27728f22016-02-17 15:46:28 +05301596 .toString();
1597 }
sunishvkf7c56552016-07-18 16:02:39 +05301598
1599 /**
1600 * Represents a Hello task which sent a hello message every configured time interval.
1601 */
1602 private class InternalHelloTimer implements Runnable {
1603
1604 /**
1605 * Creates an instance of Hello Timer.
1606 */
1607 InternalHelloTimer() {
1608 }
1609
1610 @Override
1611 public void run() {
1612 if (channel != null && channel.isOpen() && channel.isConnected()) {
1613 if (interfaceType() == OspfInterfaceType.BROADCAST.value()) {
1614 if (interfaceTypeOldValue != interfaceType()) {
1615 try {
1616 callDrElection(channel);
1617 } catch (Exception e) {
1618 log.debug("Error while calling interfaceUp {}", e.getMessage());
1619 }
1620 }
1621 } else {
1622 if (interfaceTypeOldValue != interfaceType()) {
1623 interfaceTypeOldValue = interfaceType();
1624 }
1625 }
1626 HelloPacket hellopacket = new HelloPacket();
1627 //Headers
1628 hellopacket.setOspfVer(OspfUtil.OSPF_VERSION);
1629 hellopacket.setOspftype(OspfPacketType.HELLO.value());
1630 hellopacket.setOspfPacLength(0); //will be modified while encoding
1631 hellopacket.setRouterId(ospfArea.routerId());
1632 hellopacket.setAreaId(ospfArea.areaId());
1633 hellopacket.setChecksum(0); //will be modified while encoding
1634 hellopacket.setAuthType(OspfUtil.NOT_ASSIGNED);
1635 hellopacket.setAuthentication(OspfUtil.NOT_ASSIGNED);
1636 //Body
1637 hellopacket.setNetworkMask(ipNetworkMask());
1638 hellopacket.setOptions(ospfArea.options());
1639 hellopacket.setHelloInterval(helloIntervalTime());
1640 hellopacket.setRouterPriority(routerPriority());
1641 hellopacket.setRouterDeadInterval(routerDeadIntervalTime());
1642 hellopacket.setDr(dr());
1643 hellopacket.setBdr(bdr());
1644
1645 Map<String, OspfNbr> listOfNeighbors = listOfNeighbors();
1646 Set<String> keys = listOfNeighbors.keySet();
1647 Iterator itr = keys.iterator();
1648 while (itr.hasNext()) {
1649 String nbrKey = (String) itr.next();
1650 OspfNbrImpl nbr = (OspfNbrImpl) listOfNeighbors.get(nbrKey);
1651 if (nbr.getState() != OspfNeighborState.DOWN) {
1652 hellopacket.addNeighbor(Ip4Address.valueOf(nbrKey));
1653 }
1654 }
1655 // build a hello Packet
1656 if (channel == null || !channel.isOpen() || !channel.isConnected()) {
1657 log.debug("Hello Packet not sent !!.. Channel Issue...");
1658 return;
1659 }
1660
1661 hellopacket.setDestinationIp(OspfUtil.ALL_SPF_ROUTERS);
1662 byte[] messageToWrite = getMessage(hellopacket);
1663 ChannelFuture future = channel.write(messageToWrite);
1664 if (future.isSuccess()) {
1665 log.debug("Hello Packet successfully sent !!");
1666 } else {
1667 future.awaitUninterruptibly();
1668 }
1669
1670 }
1671 }
1672 }
1673
1674 /**
1675 * Represents a Wait Timer task which waits the interface state to become WAITING.
1676 * It initiates DR election process.
1677 */
1678 private class InternalWaitTimer implements Runnable {
1679 Channel ch;
1680
1681 /**
1682 * Creates an instance of Wait Timer.
1683 */
1684 InternalWaitTimer() {
1685 this.ch = channel;
1686 }
1687
1688 @Override
1689 public void run() {
1690 log.debug("Wait timer expires...");
1691 if (ch != null && ch.isConnected()) {
1692 try {
1693 waitTimer(ch);
1694 } catch (Exception e) {
1695 log.debug("Exception at wait timer ...!!!");
1696 }
1697 }
1698 }
1699 }
1700
1701 /**
1702 * Represents a task which sent a LS Acknowledge from the link state headers list.
1703 */
1704 private class InternalDelayedAckTimer implements Runnable {
1705 Channel ch;
1706
1707 /**
1708 * Creates an instance of Delayed acknowledge timer.
1709 */
1710 InternalDelayedAckTimer() {
1711 this.ch = channel;
1712 }
1713
1714 @Override
1715 public void run() {
1716 if (!linkStateHeaders().isEmpty()) {
1717 isDelayedAckTimerScheduled = true;
1718 if (ch != null && ch.isConnected()) {
1719
1720 List<LsaHeader> listOfLsaHeadersAcknowledged = new ArrayList<>();
1721 List<LsaHeader> listOfLsaHeaders = linkStateHeaders();
1722 log.debug("Delayed Ack, Number of Lsa's to Ack {}", listOfLsaHeaders.size());
1723 Iterator itr = listOfLsaHeaders.iterator();
1724 while (itr.hasNext()) {
1725 LsAcknowledge ackContent = new LsAcknowledge();
1726 //Setting OSPF Header
1727 ackContent.setOspfVer(OspfUtil.OSPF_VERSION);
1728 ackContent.setOspftype(OspfPacketType.LSAACK.value());
1729 ackContent.setRouterId(ospfArea.routerId());
1730 ackContent.setAreaId(ospfArea.areaId());
1731 ackContent.setAuthType(OspfUtil.NOT_ASSIGNED);
1732 ackContent.setAuthentication(OspfUtil.NOT_ASSIGNED);
1733 ackContent.setOspfPacLength(OspfUtil.NOT_ASSIGNED);
1734 ackContent.setChecksum(OspfUtil.NOT_ASSIGNED);
1735 //limit to mtu
1736 int currentLength = OspfUtil.OSPF_HEADER_LENGTH;
1737 int maxSize = mtu() -
1738 OspfUtil.LSA_HEADER_LENGTH; // subtract a normal IP header.
1739 while (itr.hasNext()) {
1740 if ((currentLength + OspfUtil.LSA_HEADER_LENGTH) >= maxSize) {
1741 break;
1742 }
1743 LsaHeader lsaHeader = (LsaHeader) itr.next();
1744 ackContent.addLinkStateHeader(lsaHeader);
1745 currentLength = currentLength + OspfUtil.LSA_HEADER_LENGTH;
1746 listOfLsaHeadersAcknowledged.add(lsaHeader);
1747 log.debug("Delayed Ack, Added Lsa's to Ack {}", lsaHeader);
1748 }
1749
1750 log.debug("Delayed Ack, Number of Lsa's in LsAck packet {}",
1751 ackContent.getLinkStateHeaders().size());
1752
1753 //set the destination
1754 if (state() == OspfInterfaceState.DR || state() == OspfInterfaceState.BDR
1755 || state() == OspfInterfaceState.POINT2POINT) {
1756 ackContent.setDestinationIp(OspfUtil.ALL_SPF_ROUTERS);
1757 } else if (state() == OspfInterfaceState.DROTHER) {
1758 ackContent.setDestinationIp(OspfUtil.ALL_DROUTERS);
1759 }
1760 byte[] messageToWrite = getMessage(ackContent);
1761 ch.write(messageToWrite);
1762
1763 for (LsaHeader lsa : listOfLsaHeadersAcknowledged) {
1764 linkStateHeaders().remove(lsa);
1765 removeLsaFromNeighborMap(((OspfAreaImpl) ospfArea).getLsaKey(lsa));
1766 }
1767 }
1768 }
1769 }
1770 }
1771 }
Kalyankumar Asangi27728f22016-02-17 15:46:28 +05301772}