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