blob: 381109eb5f1779b2b46781dc54c09a99de872d32 [file] [log] [blame]
tejeshwer degala3fe1ed52016-04-22 17:04:01 +05301/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
tejeshwer degala3fe1ed52016-04-22 17:04:01 +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.isis.controller.impl;
17
18import com.fasterxml.jackson.databind.JsonNode;
19import org.jboss.netty.bootstrap.ClientBootstrap;
20import org.jboss.netty.channel.AdaptiveReceiveBufferSizePredictor;
21import org.jboss.netty.channel.ChannelFuture;
sunish vk4b5ce002016-05-09 20:18:35 +053022import org.jboss.netty.channel.ChannelFutureListener;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +053023import org.jboss.netty.channel.ChannelPipelineFactory;
24import org.jboss.netty.channel.FixedReceiveBufferSizePredictorFactory;
25import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
26import org.onlab.packet.Ip4Address;
27import org.onlab.packet.MacAddress;
28import org.onlab.packet.TpPort;
29import org.onosproject.isis.controller.IsisInterface;
30import org.onosproject.isis.controller.IsisNetworkType;
31import org.onosproject.isis.controller.IsisProcess;
32import org.onosproject.isis.controller.IsisRouterType;
sunish vk7bdf4d42016-06-24 12:29:43 +053033import org.onosproject.isis.controller.topology.IsisAgent;
34import org.onosproject.isis.controller.topology.IsisLink;
35import org.onosproject.isis.controller.topology.IsisRouter;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +053036import org.onosproject.isis.io.util.IsisConstants;
37import org.slf4j.Logger;
38import org.slf4j.LoggerFactory;
39
40import java.net.InetAddress;
41import java.net.InetSocketAddress;
sunish vk4b5ce002016-05-09 20:18:35 +053042import java.net.NetworkInterface;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +053043import java.net.UnknownHostException;
44import java.util.ArrayList;
sunish vk4b5ce002016-05-09 20:18:35 +053045import java.util.Enumeration;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +053046import java.util.List;
47import java.util.concurrent.Executors;
sunish vk4b5ce002016-05-09 20:18:35 +053048import java.util.concurrent.ScheduledExecutorService;
sunish vk7bdf4d42016-06-24 12:29:43 +053049import java.util.concurrent.ScheduledFuture;
sunish vk4b5ce002016-05-09 20:18:35 +053050import java.util.concurrent.TimeUnit;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +053051
52import static org.onlab.util.Tools.groupedThreads;
53
54/**
55 * Representation of an ISIS controller.
56 */
57public class Controller {
58 protected static final int BUFFER_SIZE = 4 * 1024 * 1024;
59 private static final Logger log = LoggerFactory.getLogger(Controller.class);
sunish vk4b5ce002016-05-09 20:18:35 +053060 private static final int RETRY_INTERVAL = 4;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +053061 private final int peerWorkerThreads = 16;
sunish vk4b5ce002016-05-09 20:18:35 +053062 byte[] configPacket = null;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +053063 private List<IsisProcess> processes = null;
64 private IsisChannelHandler isisChannelHandler;
65 private NioClientSocketChannelFactory peerExecFactory;
66 private ClientBootstrap peerBootstrap = null;
67 private TpPort isisPort = TpPort.tpPort(IsisConstants.SPORT);
sunish vk4b5ce002016-05-09 20:18:35 +053068 private ScheduledExecutorService connectExecutor = null;
69 private int connectRetryCounter = 0;
70 private int connectRetryTime;
sunish vk7bdf4d42016-06-24 12:29:43 +053071 private ScheduledFuture future = null;
72 private IsisAgent agent;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +053073
74 /**
75 * Deactivates ISIS controller.
76 */
77 public void isisDeactivate() {
sunish vk7bdf4d42016-06-24 12:29:43 +053078 disconnectExecutor();
79 processes = null;
Ray Milkey11ce9302019-02-07 14:41:17 -080080 if (peerExecFactory != null) {
81 peerExecFactory.shutdown();
82 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +053083 }
84
85 /**
sunish vk7bdf4d42016-06-24 12:29:43 +053086 * Sets ISIS agent.
87 *
88 * @param agent ISIS agent instance
89 */
90 public void setAgent(IsisAgent agent) {
91 this.agent = agent;
92 }
93
94
95 /**
tejeshwer degala3fe1ed52016-04-22 17:04:01 +053096 * Updates the processes configuration.
97 *
98 * @param jsonNode json node instance
tejeshwer degala3fe1ed52016-04-22 17:04:01 +053099 */
Ray Milkey2b4958a2018-02-06 18:59:06 -0800100 public void updateConfig(JsonNode jsonNode) {
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530101 log.debug("Controller::UpdateConfig called");
sunish vk4b5ce002016-05-09 20:18:35 +0530102 configPacket = new byte[IsisConstants.CONFIG_LENGTH];
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530103 byte numberOfInterface = 0; // number of interfaces to configure
104
105 configPacket[0] = (byte) 0xFF; // its a conf packet - identifier
106 List<IsisProcess> isisProcesses = getConfig(jsonNode);
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530107 for (IsisProcess isisProcess : isisProcesses) {
108 log.debug("IsisProcessDetails : " + isisProcess);
109 for (IsisInterface isisInterface : isisProcess.isisInterfaceList()) {
110 DefaultIsisInterface isisInterfaceImpl = (DefaultIsisInterface) isisInterface;
111 log.debug("IsisInterfaceDetails : " + isisInterface);
112 numberOfInterface++;
113 configPacket[2 * numberOfInterface] = (byte) isisInterfaceImpl.interfaceIndex();
114 if (isisInterface.networkType() == IsisNetworkType.BROADCAST &&
115 isisInterfaceImpl.reservedPacketCircuitType() == IsisRouterType.L1.value()) {
116 configPacket[(2 * numberOfInterface) + 1] = (byte) 0;
117 } else if (isisInterface.networkType() == IsisNetworkType.BROADCAST &&
118 isisInterfaceImpl.reservedPacketCircuitType() == IsisRouterType.L2.value()) {
119 configPacket[(2 * numberOfInterface) + 1] = (byte) 1;
120 } else if (isisInterface.networkType() == IsisNetworkType.P2P) {
121 configPacket[(2 * numberOfInterface) + 1] = (byte) 2;
122 } else if (isisInterface.networkType() == IsisNetworkType.BROADCAST &&
123 isisInterfaceImpl.reservedPacketCircuitType() == IsisRouterType.L1L2.value()) {
124 configPacket[(2 * numberOfInterface) + 1] = (byte) 3;
125 }
126 }
127 }
128 configPacket[1] = numberOfInterface;
129 //First time configuration
130 if (processes == null) {
Jon Hallcbd1b392017-01-18 20:15:44 -0800131 if (!isisProcesses.isEmpty()) {
sunish vk4b5ce002016-05-09 20:18:35 +0530132 processes = isisProcesses;
133 connectPeer();
sunish vk4b5ce002016-05-09 20:18:35 +0530134 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530135 } else {
136 isisChannelHandler.updateInterfaceMap(isisProcesses);
sunish vk4b5ce002016-05-09 20:18:35 +0530137 //Send the config packet
138 isisChannelHandler.sentConfigPacket(configPacket);
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530139 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530140 }
141
142 /**
143 * Initializes the netty client channel connection.
144 */
145 private void initConnection() {
146 if (peerBootstrap != null) {
147 return;
148 }
149 peerBootstrap = createPeerBootStrap();
150
151 peerBootstrap.setOption("reuseAddress", true);
152 peerBootstrap.setOption("tcpNoDelay", true);
153 peerBootstrap.setOption("keepAlive", true);
154 peerBootstrap.setOption("receiveBufferSize", Controller.BUFFER_SIZE);
155 peerBootstrap.setOption("receiveBufferSizePredictorFactory",
sunish vk7bdf4d42016-06-24 12:29:43 +0530156 new FixedReceiveBufferSizePredictorFactory(
157 Controller.BUFFER_SIZE));
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530158 peerBootstrap.setOption("receiveBufferSizePredictor",
sunish vk7bdf4d42016-06-24 12:29:43 +0530159 new AdaptiveReceiveBufferSizePredictor(64, 1024, 65536));
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530160 peerBootstrap.setOption("child.keepAlive", true);
161 peerBootstrap.setOption("child.tcpNoDelay", true);
162 peerBootstrap.setOption("child.sendBufferSize", Controller.BUFFER_SIZE);
163 peerBootstrap.setOption("child.receiveBufferSize", Controller.BUFFER_SIZE);
164 peerBootstrap.setOption("child.receiveBufferSizePredictorFactory",
sunish vk7bdf4d42016-06-24 12:29:43 +0530165 new FixedReceiveBufferSizePredictorFactory(
166 Controller.BUFFER_SIZE));
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530167 peerBootstrap.setOption("child.reuseAddress", true);
168
169 isisChannelHandler = new IsisChannelHandler(this, processes);
170 ChannelPipelineFactory pfact = new IsisPipelineFactory(isisChannelHandler);
171 peerBootstrap.setPipelineFactory(pfact);
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530172 }
173
174 /**
175 * Creates peer boot strap.
176 *
177 * @return client bootstrap instance
178 */
179 private ClientBootstrap createPeerBootStrap() {
180
181 if (peerWorkerThreads == 0) {
182 peerExecFactory = new NioClientSocketChannelFactory(
183 Executors.newCachedThreadPool(groupedThreads("onos/isis", "boss-%d")),
184 Executors.newCachedThreadPool(groupedThreads("onos/isis", "worker-%d")));
185 return new ClientBootstrap(peerExecFactory);
186 } else {
187 peerExecFactory = new NioClientSocketChannelFactory(
188 Executors.newCachedThreadPool(groupedThreads("onos/isis", "boss-%d")),
189 Executors.newCachedThreadPool(groupedThreads("onos/isis", "worker-%d")),
190 peerWorkerThreads);
191 return new ClientBootstrap(peerExecFactory);
192 }
193 }
194
195 /**
196 * Gets all configured processes.
197 *
198 * @return all configured processes
199 */
200 public List<IsisProcess> getAllConfiguredProcesses() {
201 return processes;
202 }
203
204 /**
205 * Gets the list of processes configured.
206 *
207 * @param json posted json
208 * @return list of processes configured
209 */
Ray Milkey986a47a2018-01-25 11:38:51 -0800210 private List<IsisProcess> getConfig(JsonNode json) {
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530211 List<IsisProcess> isisProcessesList = new ArrayList<>();
212 JsonNode jsonNodes = json;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530213 if (jsonNodes == null) {
214 return isisProcessesList;
215 }
216 jsonNodes.forEach(jsonNode -> {
217 List<IsisInterface> interfaceList = new ArrayList<>();
218 for (JsonNode jsonNode1 : jsonNode.path(IsisConstants.INTERFACE)) {
219 IsisInterface isisInterface = new DefaultIsisInterface();
sunish vk4b5ce002016-05-09 20:18:35 +0530220 String index = jsonNode1.path(IsisConstants.INTERFACEINDEX).asText();
221 if (isPrimitive(index)) {
222 int input = Integer.parseInt(index);
223 if (input < 1 || input > 255) {
224 log.debug("Wrong interface index: {}", index);
225 continue;
226 }
227 isisInterface.setInterfaceIndex(Integer.parseInt(index));
228 } else {
229 log.debug("Wrong interface index {}", index);
230 continue;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530231 }
sunish vk4b5ce002016-05-09 20:18:35 +0530232 Ip4Address ipAddress = getInterfaceIp(isisInterface.interfaceIndex());
233 if (ipAddress != null && !ipAddress.equals(IsisConstants.DEFAULTIP)) {
234 isisInterface.setInterfaceIpAddress(ipAddress);
235 } else {
236 log.debug("Wrong interface index {}. No matching interface in system.", index);
237 continue;
238 }
239 MacAddress macAddress = getInterfaceMac(isisInterface.interfaceIndex());
240 if (macAddress != null) {
241 isisInterface.setInterfaceMacAddress(macAddress);
242 } else {
243 log.debug("Wrong interface index {}. No matching interface in system.", index);
244 continue;
245 }
246 String mask = getInterfaceMask(isisInterface.interfaceIndex());
247 if (mask != null) {
248 try {
249 isisInterface.setNetworkMask(InetAddress.getByName(mask).getAddress());
250 } catch (UnknownHostException e) {
251 log.debug("Wrong interface index {}. Error while getting network mask.", index);
252 }
253 } else {
254 log.debug("Wrong interface index {}. Error while getting network mask.", index);
255 continue;
256 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530257 isisInterface.setIntermediateSystemName(jsonNode1
sunish vk7bdf4d42016-06-24 12:29:43 +0530258 .path(IsisConstants.INTERMEDIATESYSTEMNAME)
259 .asText());
sunish vk4b5ce002016-05-09 20:18:35 +0530260 String systemId = jsonNode1.path(IsisConstants.SYSTEMID).asText();
261 if (isValidSystemId(systemId)) {
262 isisInterface.setSystemId(systemId);
263 } else {
264 log.debug("Wrong systemId: {} for interface index {}.", systemId, index);
265 continue;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530266 }
sunish vk4b5ce002016-05-09 20:18:35 +0530267 String circuitType = jsonNode1.path(IsisConstants.RESERVEDPACKETCIRCUITTYPE).asText();
268 if (isPrimitive(circuitType)) {
269 int input = Integer.parseInt(circuitType);
270 if (input < 1 || input > 3) {
271 log.debug("Wrong ReservedPacketCircuitType: {} for interface index {}.", circuitType, index);
272 continue;
273 }
274 isisInterface.setReservedPacketCircuitType(input);
275 } else {
276 log.debug("Wrong ReservedPacketCircuitType: {} for interface index {}.", circuitType, index);
277 continue;
278 }
279 String networkType = jsonNode1.path(IsisConstants.NETWORKTYPE).asText();
280 if (isPrimitive(networkType)) {
281 int input = Integer.parseInt(networkType);
282 if (input < 1 || input > 2) {
283 log.debug("Wrong networkType: {} for interface index {}.", networkType, index);
284 continue;
285 }
286 isisInterface.setNetworkType(IsisNetworkType.get(input));
287 } else {
288 log.debug("Wrong networkType: {} for interface index {}.", networkType, index);
289 continue;
290 }
291 String areaAddress = jsonNode1.path(IsisConstants.AREAADDRESS).asText();
292 if (isPrimitive(areaAddress)) {
293 if (areaAddress.length() > 7) {
294 log.debug("Wrong areaAddress: {} for interface index {}.", areaAddress, index);
295 continue;
296 }
297 isisInterface.setAreaAddress(areaAddress);
298 } else {
299 log.debug("Wrong areaAddress: {} for interface index {}.", areaAddress, index);
300 continue;
301 }
302 String circuitId = jsonNode1.path(IsisConstants.CIRCUITID).asText();
303 if (isPrimitive(circuitId)) {
304 int input = Integer.parseInt(circuitId);
305 if (input < 1) {
306 log.debug("Wrong circuitId: {} for interface index {}.", circuitId, index);
307 continue;
308 }
309 isisInterface.setCircuitId(circuitId);
310 } else {
311 log.debug("Wrong circuitId: {} for interface index {}.", circuitId, index);
312 continue;
313 }
314 String holdingTime = jsonNode1.path(IsisConstants.HOLDINGTIME).asText();
315 if (isPrimitive(holdingTime)) {
316 int input = Integer.parseInt(holdingTime);
317 if (input < 1 || input > 255) {
318 log.debug("Wrong holdingTime: {} for interface index {}.", holdingTime, index);
319 continue;
320 }
321 isisInterface.setHoldingTime(input);
322 } else {
323 log.debug("Wrong holdingTime: {} for interface index {}.", holdingTime, index);
324 continue;
325 }
326 String helloInterval = jsonNode1.path(IsisConstants.HELLOINTERVAL).asText();
327 if (isPrimitive(helloInterval)) {
328 int interval = Integer.parseInt(helloInterval);
329 if (interval > 0 && interval <= 255) {
330 isisInterface.setHelloInterval(interval);
331 } else {
332 log.debug("Wrong hello interval: {} for interface index {}.", helloInterval, index);
333 continue;
334 }
335 } else {
336 log.debug("Wrong hello interval: {} for interface index {}.", helloInterval, index);
337 continue;
338 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530339 interfaceList.add(isisInterface);
340 }
Jon Hallcbd1b392017-01-18 20:15:44 -0800341 if (!interfaceList.isEmpty()) {
sunish vk4b5ce002016-05-09 20:18:35 +0530342 IsisProcess process = new DefaultIsisProcess();
343 process.setProcessId(jsonNode.path(IsisConstants.PROCESSESID).asText());
344 process.setIsisInterfaceList(interfaceList);
345 isisProcessesList.add(process);
346 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530347 });
348
349 return isisProcessesList;
350 }
sunish vk4b5ce002016-05-09 20:18:35 +0530351
352 /**
353 * Returns interface MAC by index.
354 *
355 * @param interfaceIndex interface index
356 * @return interface IP by index
357 */
358 private MacAddress getInterfaceMac(int interfaceIndex) {
359 MacAddress macAddress = null;
360 try {
361 NetworkInterface networkInterface = NetworkInterface.getByIndex(interfaceIndex);
362 macAddress = MacAddress.valueOf(networkInterface.getHardwareAddress());
363 } catch (Exception e) {
364 log.debug("Error while getting Interface IP by index");
365 return macAddress;
366 }
367
368 return macAddress;
369 }
370
371 /**
372 * Returns interface IP by index.
373 *
374 * @param interfaceIndex interface index
375 * @return interface IP by index
376 */
377 private Ip4Address getInterfaceIp(int interfaceIndex) {
378 Ip4Address ipAddress = null;
379 try {
380 NetworkInterface networkInterface = NetworkInterface.getByIndex(interfaceIndex);
381 Enumeration ipAddresses = networkInterface.getInetAddresses();
382 while (ipAddresses.hasMoreElements()) {
383 InetAddress address = (InetAddress) ipAddresses.nextElement();
384 if (!address.isLinkLocalAddress()) {
385 ipAddress = Ip4Address.valueOf(address.getAddress());
386 break;
387 }
388 }
389 } catch (Exception e) {
390 log.debug("Error while getting Interface IP by index");
391 return IsisConstants.DEFAULTIP;
392 }
393 return ipAddress;
394 }
395
396 /**
397 * Returns interface MAC by index.
398 *
399 * @param interfaceIndex interface index
400 * @return interface IP by index
401 */
402 private String getInterfaceMask(int interfaceIndex) {
403 String subnetMask = null;
404 try {
405 Ip4Address ipAddress = getInterfaceIp(interfaceIndex);
406 NetworkInterface networkInterface = NetworkInterface.getByInetAddress(
407 InetAddress.getByName(ipAddress.toString()));
408 Enumeration ipAddresses = networkInterface.getInetAddresses();
409 int index = 0;
410 while (ipAddresses.hasMoreElements()) {
411 InetAddress address = (InetAddress) ipAddresses.nextElement();
412 if (!address.isLinkLocalAddress()) {
413 break;
414 }
415 index++;
416 }
417 int prfLen = networkInterface.getInterfaceAddresses().get(index).getNetworkPrefixLength();
418 int shft = 0xffffffff << (32 - prfLen);
419 int oct1 = ((byte) ((shft & 0xff000000) >> 24)) & 0xff;
420 int oct2 = ((byte) ((shft & 0x00ff0000) >> 16)) & 0xff;
421 int oct3 = ((byte) ((shft & 0x0000ff00) >> 8)) & 0xff;
422 int oct4 = ((byte) (shft & 0x000000ff)) & 0xff;
423 subnetMask = oct1 + "." + oct2 + "." + oct3 + "." + oct4;
424 } catch (Exception e) {
425 log.debug("Error while getting Interface network mask by index");
426 return subnetMask;
427 }
428 return subnetMask;
429 }
430
431 /**
432 * Checks if primitive or not.
433 *
434 * @param value input value
435 * @return true if number else false
436 */
437 private boolean isPrimitive(String value) {
438 boolean status = true;
439 value = value.trim();
440 if (value.length() < 1) {
441 return false;
442 }
443 for (int i = 0; i < value.length(); i++) {
444 char c = value.charAt(i);
445 if (!Character.isDigit(c)) {
446 status = false;
447 break;
448 }
449 }
450
451 return status;
452 }
453
454 /**
455 * Checks if system id is valid or not.
456 *
457 * @param value input value
458 * @return true if valid else false
459 */
460 private boolean isValidSystemId(String value) {
461 value = value.trim();
462 boolean status = true;
463 if (value.length() != 14) {
464 return false;
465 }
466 for (int i = 0; i < value.length(); i++) {
467 char c = value.charAt(i);
468 if (!Character.isDigit(c)) {
469 if (!((i == 4 || i == 9) && c == '.')) {
470 status = false;
471 break;
472 }
473 }
474 }
475
476 return status;
477 }
478
479 /**
480 * Disconnects the executor.
481 */
482 public void disconnectExecutor() {
483 if (connectExecutor != null) {
sunish vk7bdf4d42016-06-24 12:29:43 +0530484 future.cancel(true);
485 connectExecutor.shutdownNow();
sunish vk4b5ce002016-05-09 20:18:35 +0530486 connectExecutor = null;
487 }
488 }
489
490 /**
491 * Connects to peer.
492 */
493 public void connectPeer() {
494 scheduleConnectionRetry(this.connectRetryTime);
495 }
496
497 /**
498 * Retry connection with exponential back-off mechanism.
499 *
500 * @param retryDelay retry delay
501 */
502 private void scheduleConnectionRetry(long retryDelay) {
sunish vk7bdf4d42016-06-24 12:29:43 +0530503 if (connectExecutor == null) {
504 connectExecutor = Executors.newSingleThreadScheduledExecutor();
sunish vk4b5ce002016-05-09 20:18:35 +0530505 }
sunish vk7bdf4d42016-06-24 12:29:43 +0530506 future = connectExecutor.schedule(new ConnectionRetry(), retryDelay, TimeUnit.MINUTES);
507 }
508
509 /**
510 * Adds device details.
511 *
512 * @param isisRouter ISIS router instance
513 */
514 public void addDeviceDetails(IsisRouter isisRouter) {
515 agent.addConnectedRouter(isisRouter);
516 }
517
518 /**
519 * Removes device details.
520 *
521 * @param isisRouter Isis router instance
522 */
523 public void removeDeviceDetails(IsisRouter isisRouter) {
524 agent.removeConnectedRouter(isisRouter);
525 }
526
527 /**
528 * Adds link details.
529 *
530 * @param isisLink ISIS link instance
531 */
532 public void addLinkDetails(IsisLink isisLink) {
533 agent.addLink(isisLink);
534 }
535
536 /**
537 * Removes link details.
538 *
539 * @param isisLink ISIS link instance
540 */
541 public void removeLinkDetails(IsisLink isisLink) {
542 agent.deleteLink(isisLink);
543 }
544
545 /**
546 * Returns the isisAgent instance.
547 *
548 * @return agent
549 */
550 public IsisAgent agent() {
551 return this.agent;
sunish vk4b5ce002016-05-09 20:18:35 +0530552 }
553
554 /**
555 * Implements ISIS connection and manages connection to peer with back-off mechanism in case of failure.
556 */
557 class ConnectionRetry implements Runnable {
558 @Override
559 public void run() {
560 log.debug("Connect to peer {}", IsisConstants.SHOST);
561 initConnection();
sunish vkc3824e82016-05-11 19:38:24 +0530562 isisChannelHandler.sentConfigPacket(configPacket);
sunish vk4b5ce002016-05-09 20:18:35 +0530563 InetSocketAddress connectToSocket = new InetSocketAddress(IsisConstants.SHOST, isisPort.toInt());
564 try {
565 peerBootstrap.connect(connectToSocket).addListener(new ChannelFutureListener() {
566 @Override
567 public void operationComplete(ChannelFuture future) throws Exception {
568 if (!future.isSuccess()) {
569 connectRetryCounter++;
570 log.error("Connection failed, ConnectRetryCounter {} remote host {}", connectRetryCounter,
sunish vk7bdf4d42016-06-24 12:29:43 +0530571 IsisConstants.SHOST);
sunish vk4b5ce002016-05-09 20:18:35 +0530572 /*
573 * Reconnect to peer on failure is exponential till 4 mins, later on retry after every 4
574 * mins.
575 */
576 if (connectRetryTime < RETRY_INTERVAL) {
577 connectRetryTime = (connectRetryTime != 0) ? connectRetryTime * 2 : 1;
578 }
579 scheduleConnectionRetry(connectRetryTime);
580 } else {
sunish vkc3824e82016-05-11 19:38:24 +0530581 //Send the config packet
582 isisChannelHandler.sentConfigPacket(configPacket);
sunish vk4b5ce002016-05-09 20:18:35 +0530583 connectRetryCounter++;
584 log.info("Connected to remote host {}, Connect Counter {}", IsisConstants.SHOST,
sunish vk7bdf4d42016-06-24 12:29:43 +0530585 connectRetryCounter);
sunish vk4b5ce002016-05-09 20:18:35 +0530586 disconnectExecutor();
sunish vkc3824e82016-05-11 19:38:24 +0530587
sunish vk4b5ce002016-05-09 20:18:35 +0530588 return;
589 }
590 }
591 });
592 } catch (Exception e) {
593 log.info("Connect peer exception : " + e.toString());
594 disconnectExecutor();
595 }
596 }
597 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530598}