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