blob: 794d623cd47d46b5c2570c04edb5a6106df68702 [file] [log] [blame]
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +05301/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +05303 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.ospf.controller.lsdb;
17
18import com.google.common.base.Objects;
19import org.jboss.netty.channel.Channel;
20import org.onosproject.ospf.controller.LsaBin;
21import org.onosproject.ospf.controller.LsaWrapper;
22import org.onosproject.ospf.controller.LsdbAge;
23import org.onosproject.ospf.controller.OspfArea;
24import org.onosproject.ospf.controller.area.OspfAreaImpl;
25import org.onosproject.ospf.protocol.util.OspfParameters;
26import org.slf4j.Logger;
27import org.slf4j.LoggerFactory;
28
29import java.util.Map;
30import java.util.concurrent.ArrayBlockingQueue;
31import java.util.concurrent.BlockingQueue;
32import java.util.concurrent.ConcurrentHashMap;
33import java.util.concurrent.Executors;
34import java.util.concurrent.ScheduledExecutorService;
35import java.util.concurrent.TimeUnit;
36
37/**
38 * Representation of LSDB Aging process.
39 */
40public class LsdbAgeImpl implements LsdbAge {
41
42 private static final Logger log =
43 LoggerFactory.getLogger(LsdbAgeImpl.class);
sunishvkf7c56552016-07-18 16:02:39 +053044 protected static int ageCounter = 0;
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +053045 private InternalAgeTimer dbAgeTimer;
46 private ScheduledExecutorService exServiceage;
47 // creating age bins of MAXAGE
48 private Map<Integer, LsaBin> ageBins = new ConcurrentHashMap<>(OspfParameters.MAXAGE);
49 private LsaBin maxAgeBin = new LsaBinImpl(OspfParameters.MAXAGE);
50 private int ageCounterRollOver = 0;
51 private Channel channel = null;
52 private LsaQueueConsumer queueConsumer = null;
53 private BlockingQueue<LsaWrapper> lsaQueue = new ArrayBlockingQueue(1024);
54 private OspfArea ospfArea = null;
55
56
57 /**
58 * Creates an instance of LSDB age.
59 *
60 * @param ospfArea OSPF area instance
61 */
62 public LsdbAgeImpl(OspfArea ospfArea) {
63 // create LSBin's in the HashMap.
64 for (int i = 0; i < OspfParameters.MAXAGE; i++) {
65 LsaBin lsaBin = new LsaBinImpl(i);
66 ageBins.put(i, lsaBin);
67 }
68 this.ospfArea = ospfArea;
69 }
70
71 @Override
72 public boolean equals(Object o) {
73 if (this == o) {
74 return true;
75 }
76 if (o == null || getClass() != o.getClass()) {
77 return false;
78 }
79 LsdbAgeImpl that = (LsdbAgeImpl) o;
80 return Objects.equal(ageBins, that.ageBins) &&
81 Objects.equal(ageCounter, that.ageCounter) &&
82 Objects.equal(ageCounterRollOver, that.ageCounterRollOver) &&
Yuta HIGUCHI1edc36b2018-01-24 23:39:06 -080083 Objects.equal(lsaQueue, that.lsaQueue);
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +053084 }
85
86 @Override
87 public int hashCode() {
88 return Objects.hashCode(ageBins, ageCounter, ageCounterRollOver, lsaQueue);
89 }
90
91 /**
92 * Adds LSA to bin.
93 *
94 * @param binKey key to store in bin
95 * @param lsaBin LSA bin instance
96 */
Yuta HIGUCHI1edc36b2018-01-24 23:39:06 -080097 @Override
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +053098 public void addLsaBin(Integer binKey, LsaBin lsaBin) {
99 if (!ageBins.containsKey(binKey)) {
100 ageBins.put(binKey, lsaBin);
101 }
102 }
103
104 /**
105 * Gets LSA from Bin.
106 *
107 * @param binKey key
108 * @return bin instance
109 */
Yuta HIGUCHI1edc36b2018-01-24 23:39:06 -0800110 @Override
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530111 public LsaBin getLsaBin(Integer binKey) {
112
113 return ageBins.get(binKey);
114 }
115
116 /**
117 * Adds the LSA to maxAge bin.
118 *
119 * @param key key
120 * @param wrapper wrapper instance
121 */
Yuta HIGUCHI1edc36b2018-01-24 23:39:06 -0800122 @Override
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530123 public void addLsaToMaxAgeBin(String key, LsaWrapper wrapper) {
124 maxAgeBin.addOspfLsa(key, wrapper);
125 }
126
127 /**
128 * Removes LSA from Bin.
129 *
130 * @param lsaWrapper wrapper instance
131 */
Yuta HIGUCHI1edc36b2018-01-24 23:39:06 -0800132 @Override
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530133 public void removeLsaFromBin(LsaWrapper lsaWrapper) {
134 if (ageBins.containsKey(lsaWrapper.binNumber())) {
135 LsaBin lsaBin = ageBins.get(lsaWrapper.binNumber());
136 lsaBin.removeOspfLsa(((OspfAreaImpl) ospfArea).getLsaKey(((LsaWrapperImpl)
137 lsaWrapper).lsaHeader()), lsaWrapper);
138 }
139 }
140
141 /**
142 * Starts the aging timer and queue consumer.
143 */
Yuta HIGUCHI1edc36b2018-01-24 23:39:06 -0800144 @Override
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530145 public void startDbAging() {
146 startDbAgeTimer();
147 queueConsumer = new LsaQueueConsumer(lsaQueue, channel, ospfArea);
148 new Thread(queueConsumer).start();
149 }
150
151
152 /**
153 * Gets called every 1 second as part of the timer.
154 */
Yuta HIGUCHI1edc36b2018-01-24 23:39:06 -0800155 @Override
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530156 public void ageLsaAndFlood() {
157 //every 5 mins checksum validation
158 checkAges();
159 //every 30 mins - flood LSA
160 refreshLsa();
161 //every 60 mins - flood LSA
162 maxAgeLsa();
163
164 if (ageCounter == OspfParameters.MAXAGE) {
165 ageCounter = 0;
166 ageCounterRollOver++;
167 } else {
168 //increment age bin
169 ageCounter++;
170 }
171 }
172
173 /**
174 * If the LSA have completed the MaxAge - they are moved called stop aging and flooded.
175 */
Yuta HIGUCHI1edc36b2018-01-24 23:39:06 -0800176 @Override
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530177 public void maxAgeLsa() {
178 if (ageCounter == 0) {
179 return;
180 }
181 //Get from Age Bins
182 LsaBin lsaBin = ageBins.get(ageCounter - 1);
183 if (lsaBin == null) {
184 return;
185 }
186 Map lsaBinMap = lsaBin.listOfLsa();
187 for (Object key : lsaBinMap.keySet()) {
Yuta HIGUCHI1edc36b2018-01-24 23:39:06 -0800188 LsaWrapper lsa = (LsaWrapper) lsaBinMap.get(key);
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530189 if (lsa.currentAge() == OspfParameters.MAXAGE) {
190 lsa.setLsaProcessing(OspfParameters.MAXAGELSA);
191 log.debug("Lsa picked for maxage flooding. Age Counter: {}, AgeCounterRollover: {}, " +
192 "AgeCounterRollover WhenAddedToDb: {}, LSA Type: {}, LSA Key: {}",
193 ageCounter, ageCounterRollOver, lsa.currentAge(), lsa.lsaType(), key);
194 //add it to lsaQueue for processing
195 try {
196 lsaQueue.put(lsa);
197 //remove from bin
198 lsaBin.removeOspfLsa((String) key, lsa);
199 } catch (InterruptedException e) {
200 log.debug("Error::LSDBAge::maxAgeLsa::{}", e.getMessage());
201 }
202 }
203 }
204
205 //Get from maxAgeBin
206 Map lsaMaxAgeBinMap = maxAgeBin.listOfLsa();
207 for (Object key : lsaMaxAgeBinMap.keySet()) {
Yuta HIGUCHI1edc36b2018-01-24 23:39:06 -0800208 LsaWrapper lsa = (LsaWrapper) lsaMaxAgeBinMap.get(key);
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530209 lsa.setLsaProcessing(OspfParameters.MAXAGELSA);
210 log.debug("Lsa picked for maxage flooding. Age Counter: {}, LSA Type: {}, LSA Key: {}",
211 ageCounter, lsa.lsaType(), key);
212 //add it to lsaQueue for processing
213 try {
214 lsaQueue.put(lsa);
215 //remove from bin
216 maxAgeBin.removeOspfLsa((String) key, lsa);
217 } catch (InterruptedException e) {
218 log.debug("Error::LSDBAge::maxAgeLsa::{}", e.getMessage());
219 }
220 }
221 }
222
223
224 /*
225 * If the LSA is in age bin of 1800 - it's pushed into refresh list.
226 */
Yuta HIGUCHI1edc36b2018-01-24 23:39:06 -0800227 @Override
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530228 public void refreshLsa() {
229 int binNumber;
230 if (ageCounter < OspfParameters.LSREFRESHTIME) {
231 binNumber = ageCounter + OspfParameters.LSREFRESHTIME;
232 } else {
233 binNumber = ageCounter - OspfParameters.LSREFRESHTIME;
234 }
235 LsaBin lsaBin = ageBins.get(binNumber);
236 if (lsaBin == null) {
237 return;
238 }
239 Map lsaBinMap = lsaBin.listOfLsa();
240 for (Object key : lsaBinMap.keySet()) {
Yuta HIGUCHI1edc36b2018-01-24 23:39:06 -0800241 LsaWrapper lsa = (LsaWrapper) lsaBinMap.get(key);
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530242 try {
243 if (lsa.isSelfOriginated()) {
244 log.debug("Lsa picked for refreshLsa. binNumber: {}, LSA Type: {}, LSA Key: {}",
245 binNumber, lsa.lsaType(), key);
246 lsa.setLsaProcessing(OspfParameters.REFRESHLSA);
247 lsaQueue.put(lsa);
248 //remove from bin
249 lsaBin.removeOspfLsa((String) key, lsa);
250 }
251 } catch (InterruptedException e) {
252 log.debug("Error::LSDBAge::refreshLsa::{}", e.getMessage());
253 }
254 }
255 }
256
257 /**
258 * Verify the checksum for the LSAs who are in bins of 300 and it's multiples.
259 */
260 public void checkAges() {
261 //evry 5 min age counter + multiples of 300
262 for (int age = OspfParameters.CHECKAGE; age < OspfParameters.MAXAGE;
263 age += OspfParameters.CHECKAGE) {
264 LsaBin lsaBin = ageBins.get(age2Bin(age));
265 if (lsaBin == null) {
266 continue;
267 }
268 Map lsaBinMap = lsaBin.listOfLsa();
269 for (Object key : lsaBinMap.keySet()) {
Yuta HIGUCHI1edc36b2018-01-24 23:39:06 -0800270 LsaWrapper lsa = (LsaWrapper) lsaBinMap.get(key);
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530271 lsa.setLsaProcessing(OspfParameters.VERIFYCHECKSUM);
272 try {
273 lsaQueue.put(lsa);
274 } catch (InterruptedException e) {
275 log.debug("Error::LSDBAge::checkAges::{}", e.getMessage());
276 }
277 }
278 }
279 }
280
281
282 /**
283 * Starts DB age timer method start the aging task.
284 */
285 private void startDbAgeTimer() {
286 log.debug("OSPFNbr::startWaitTimer");
287 dbAgeTimer = new InternalAgeTimer();
288 //from 1 sec
289 exServiceage = Executors.newSingleThreadScheduledExecutor();
290 exServiceage.scheduleAtFixedRate(dbAgeTimer, OspfParameters.AGECOUNTER,
291 OspfParameters.AGECOUNTER, TimeUnit.SECONDS);
292 }
293
294 /**
295 * Stops the aging task.
296 */
297 private void stopDbAgeTimer() {
298 log.debug("OSPFNbr::stopWaitTimer ");
299 exServiceage.shutdown();
300 }
301
302
303 /**
304 * Gets the netty channel.
305 *
306 * @return netty channel
307 */
308 public Channel getChannel() {
309 return channel;
310 }
311
312 /**
313 * Sets the netty channel.
314 *
315 * @param channel netty channel
316 */
317 public void setChannel(Channel channel) {
318
319 this.channel = channel;
320 if (queueConsumer != null) {
321 queueConsumer.setChannel(channel);
322 }
323 }
324
325 /**
326 * Gets the age counter.
327 *
328 * @return ageCounter
329 */
Yuta HIGUCHI1edc36b2018-01-24 23:39:06 -0800330 @Override
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530331 public int getAgeCounter() {
332 return ageCounter;
333 }
334
335 /**
336 * Gets the age counter roll over value.
337 *
338 * @return the age counter roll over value
339 */
Yuta HIGUCHI1edc36b2018-01-24 23:39:06 -0800340 @Override
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530341 public int getAgeCounterRollOver() {
342 return ageCounterRollOver;
343 }
344
345 /**
346 * Gets the max age bin.
347 *
348 * @return lsa bin instance
349 */
Yuta HIGUCHI1edc36b2018-01-24 23:39:06 -0800350 @Override
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530351 public LsaBin getMaxAgeBin() {
352 return maxAgeBin;
353 }
354
355 /**
356 * Gets the bin number.
357 *
358 * @param x Can be either age or ageCounter
359 * @return bin number.
360 */
Yuta HIGUCHI1edc36b2018-01-24 23:39:06 -0800361 @Override
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530362 public int age2Bin(int x) {
363 if (x <= ageCounter) {
364 return (ageCounter - x);
365 } else {
366 return ((OspfParameters.MAXAGE - 1) + (ageCounter - x));
367 }
368 }
369
370 /**
371 * Runnable task which runs every second and calls aging process.
372 */
373 private class InternalAgeTimer implements Runnable {
374
375 /**
376 * Constructor.
377 */
378 InternalAgeTimer() {
379 log.debug("Starts::LsdbAge::AgeTimer...!!! ");
380 }
381
382 @Override
383 public void run() {
384 ageLsaAndFlood();
385 }
386 }
387}