blob: 8e1006e2d134dfdc6954932814985080d4f7cade [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;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +053080 peerExecFactory.shutdown();
81 }
82
83 /**
sunish vk7bdf4d42016-06-24 12:29:43 +053084 * Sets ISIS agent.
85 *
86 * @param agent ISIS agent instance
87 */
88 public void setAgent(IsisAgent agent) {
89 this.agent = agent;
90 }
91
92
93 /**
tejeshwer degala3fe1ed52016-04-22 17:04:01 +053094 * Updates the processes configuration.
95 *
96 * @param jsonNode json node instance
tejeshwer degala3fe1ed52016-04-22 17:04:01 +053097 */
Ray Milkey2b4958a2018-02-06 18:59:06 -080098 public void updateConfig(JsonNode jsonNode) {
tejeshwer degala3fe1ed52016-04-22 17:04:01 +053099 log.debug("Controller::UpdateConfig called");
sunish vk4b5ce002016-05-09 20:18:35 +0530100 configPacket = new byte[IsisConstants.CONFIG_LENGTH];
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530101 byte numberOfInterface = 0; // number of interfaces to configure
102
103 configPacket[0] = (byte) 0xFF; // its a conf packet - identifier
104 List<IsisProcess> isisProcesses = getConfig(jsonNode);
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530105 for (IsisProcess isisProcess : isisProcesses) {
106 log.debug("IsisProcessDetails : " + isisProcess);
107 for (IsisInterface isisInterface : isisProcess.isisInterfaceList()) {
108 DefaultIsisInterface isisInterfaceImpl = (DefaultIsisInterface) isisInterface;
109 log.debug("IsisInterfaceDetails : " + isisInterface);
110 numberOfInterface++;
111 configPacket[2 * numberOfInterface] = (byte) isisInterfaceImpl.interfaceIndex();
112 if (isisInterface.networkType() == IsisNetworkType.BROADCAST &&
113 isisInterfaceImpl.reservedPacketCircuitType() == IsisRouterType.L1.value()) {
114 configPacket[(2 * numberOfInterface) + 1] = (byte) 0;
115 } else if (isisInterface.networkType() == IsisNetworkType.BROADCAST &&
116 isisInterfaceImpl.reservedPacketCircuitType() == IsisRouterType.L2.value()) {
117 configPacket[(2 * numberOfInterface) + 1] = (byte) 1;
118 } else if (isisInterface.networkType() == IsisNetworkType.P2P) {
119 configPacket[(2 * numberOfInterface) + 1] = (byte) 2;
120 } else if (isisInterface.networkType() == IsisNetworkType.BROADCAST &&
121 isisInterfaceImpl.reservedPacketCircuitType() == IsisRouterType.L1L2.value()) {
122 configPacket[(2 * numberOfInterface) + 1] = (byte) 3;
123 }
124 }
125 }
126 configPacket[1] = numberOfInterface;
127 //First time configuration
128 if (processes == null) {
Jon Hallcbd1b392017-01-18 20:15:44 -0800129 if (!isisProcesses.isEmpty()) {
sunish vk4b5ce002016-05-09 20:18:35 +0530130 processes = isisProcesses;
131 connectPeer();
sunish vk4b5ce002016-05-09 20:18:35 +0530132 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530133 } else {
134 isisChannelHandler.updateInterfaceMap(isisProcesses);
sunish vk4b5ce002016-05-09 20:18:35 +0530135 //Send the config packet
136 isisChannelHandler.sentConfigPacket(configPacket);
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530137 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530138 }
139
140 /**
141 * Initializes the netty client channel connection.
142 */
143 private void initConnection() {
144 if (peerBootstrap != null) {
145 return;
146 }
147 peerBootstrap = createPeerBootStrap();
148
149 peerBootstrap.setOption("reuseAddress", true);
150 peerBootstrap.setOption("tcpNoDelay", true);
151 peerBootstrap.setOption("keepAlive", true);
152 peerBootstrap.setOption("receiveBufferSize", Controller.BUFFER_SIZE);
153 peerBootstrap.setOption("receiveBufferSizePredictorFactory",
sunish vk7bdf4d42016-06-24 12:29:43 +0530154 new FixedReceiveBufferSizePredictorFactory(
155 Controller.BUFFER_SIZE));
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530156 peerBootstrap.setOption("receiveBufferSizePredictor",
sunish vk7bdf4d42016-06-24 12:29:43 +0530157 new AdaptiveReceiveBufferSizePredictor(64, 1024, 65536));
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530158 peerBootstrap.setOption("child.keepAlive", true);
159 peerBootstrap.setOption("child.tcpNoDelay", true);
160 peerBootstrap.setOption("child.sendBufferSize", Controller.BUFFER_SIZE);
161 peerBootstrap.setOption("child.receiveBufferSize", Controller.BUFFER_SIZE);
162 peerBootstrap.setOption("child.receiveBufferSizePredictorFactory",
sunish vk7bdf4d42016-06-24 12:29:43 +0530163 new FixedReceiveBufferSizePredictorFactory(
164 Controller.BUFFER_SIZE));
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530165 peerBootstrap.setOption("child.reuseAddress", true);
166
167 isisChannelHandler = new IsisChannelHandler(this, processes);
168 ChannelPipelineFactory pfact = new IsisPipelineFactory(isisChannelHandler);
169 peerBootstrap.setPipelineFactory(pfact);
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530170 }
171
172 /**
173 * Creates peer boot strap.
174 *
175 * @return client bootstrap instance
176 */
177 private ClientBootstrap createPeerBootStrap() {
178
179 if (peerWorkerThreads == 0) {
180 peerExecFactory = new NioClientSocketChannelFactory(
181 Executors.newCachedThreadPool(groupedThreads("onos/isis", "boss-%d")),
182 Executors.newCachedThreadPool(groupedThreads("onos/isis", "worker-%d")));
183 return new ClientBootstrap(peerExecFactory);
184 } else {
185 peerExecFactory = new NioClientSocketChannelFactory(
186 Executors.newCachedThreadPool(groupedThreads("onos/isis", "boss-%d")),
187 Executors.newCachedThreadPool(groupedThreads("onos/isis", "worker-%d")),
188 peerWorkerThreads);
189 return new ClientBootstrap(peerExecFactory);
190 }
191 }
192
193 /**
194 * Gets all configured processes.
195 *
196 * @return all configured processes
197 */
198 public List<IsisProcess> getAllConfiguredProcesses() {
199 return processes;
200 }
201
202 /**
203 * Gets the list of processes configured.
204 *
205 * @param json posted json
206 * @return list of processes configured
207 */
Ray Milkey986a47a2018-01-25 11:38:51 -0800208 private List<IsisProcess> getConfig(JsonNode json) {
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530209 List<IsisProcess> isisProcessesList = new ArrayList<>();
210 JsonNode jsonNodes = json;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530211 if (jsonNodes == null) {
212 return isisProcessesList;
213 }
214 jsonNodes.forEach(jsonNode -> {
215 List<IsisInterface> interfaceList = new ArrayList<>();
216 for (JsonNode jsonNode1 : jsonNode.path(IsisConstants.INTERFACE)) {
217 IsisInterface isisInterface = new DefaultIsisInterface();
sunish vk4b5ce002016-05-09 20:18:35 +0530218 String index = jsonNode1.path(IsisConstants.INTERFACEINDEX).asText();
219 if (isPrimitive(index)) {
220 int input = Integer.parseInt(index);
221 if (input < 1 || input > 255) {
222 log.debug("Wrong interface index: {}", index);
223 continue;
224 }
225 isisInterface.setInterfaceIndex(Integer.parseInt(index));
226 } else {
227 log.debug("Wrong interface index {}", index);
228 continue;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530229 }
sunish vk4b5ce002016-05-09 20:18:35 +0530230 Ip4Address ipAddress = getInterfaceIp(isisInterface.interfaceIndex());
231 if (ipAddress != null && !ipAddress.equals(IsisConstants.DEFAULTIP)) {
232 isisInterface.setInterfaceIpAddress(ipAddress);
233 } else {
234 log.debug("Wrong interface index {}. No matching interface in system.", index);
235 continue;
236 }
237 MacAddress macAddress = getInterfaceMac(isisInterface.interfaceIndex());
238 if (macAddress != null) {
239 isisInterface.setInterfaceMacAddress(macAddress);
240 } else {
241 log.debug("Wrong interface index {}. No matching interface in system.", index);
242 continue;
243 }
244 String mask = getInterfaceMask(isisInterface.interfaceIndex());
245 if (mask != null) {
246 try {
247 isisInterface.setNetworkMask(InetAddress.getByName(mask).getAddress());
248 } catch (UnknownHostException e) {
249 log.debug("Wrong interface index {}. Error while getting network mask.", index);
250 }
251 } else {
252 log.debug("Wrong interface index {}. Error while getting network mask.", index);
253 continue;
254 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530255 isisInterface.setIntermediateSystemName(jsonNode1
sunish vk7bdf4d42016-06-24 12:29:43 +0530256 .path(IsisConstants.INTERMEDIATESYSTEMNAME)
257 .asText());
sunish vk4b5ce002016-05-09 20:18:35 +0530258 String systemId = jsonNode1.path(IsisConstants.SYSTEMID).asText();
259 if (isValidSystemId(systemId)) {
260 isisInterface.setSystemId(systemId);
261 } else {
262 log.debug("Wrong systemId: {} for interface index {}.", systemId, index);
263 continue;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530264 }
sunish vk4b5ce002016-05-09 20:18:35 +0530265 String circuitType = jsonNode1.path(IsisConstants.RESERVEDPACKETCIRCUITTYPE).asText();
266 if (isPrimitive(circuitType)) {
267 int input = Integer.parseInt(circuitType);
268 if (input < 1 || input > 3) {
269 log.debug("Wrong ReservedPacketCircuitType: {} for interface index {}.", circuitType, index);
270 continue;
271 }
272 isisInterface.setReservedPacketCircuitType(input);
273 } else {
274 log.debug("Wrong ReservedPacketCircuitType: {} for interface index {}.", circuitType, index);
275 continue;
276 }
277 String networkType = jsonNode1.path(IsisConstants.NETWORKTYPE).asText();
278 if (isPrimitive(networkType)) {
279 int input = Integer.parseInt(networkType);
280 if (input < 1 || input > 2) {
281 log.debug("Wrong networkType: {} for interface index {}.", networkType, index);
282 continue;
283 }
284 isisInterface.setNetworkType(IsisNetworkType.get(input));
285 } else {
286 log.debug("Wrong networkType: {} for interface index {}.", networkType, index);
287 continue;
288 }
289 String areaAddress = jsonNode1.path(IsisConstants.AREAADDRESS).asText();
290 if (isPrimitive(areaAddress)) {
291 if (areaAddress.length() > 7) {
292 log.debug("Wrong areaAddress: {} for interface index {}.", areaAddress, index);
293 continue;
294 }
295 isisInterface.setAreaAddress(areaAddress);
296 } else {
297 log.debug("Wrong areaAddress: {} for interface index {}.", areaAddress, index);
298 continue;
299 }
300 String circuitId = jsonNode1.path(IsisConstants.CIRCUITID).asText();
301 if (isPrimitive(circuitId)) {
302 int input = Integer.parseInt(circuitId);
303 if (input < 1) {
304 log.debug("Wrong circuitId: {} for interface index {}.", circuitId, index);
305 continue;
306 }
307 isisInterface.setCircuitId(circuitId);
308 } else {
309 log.debug("Wrong circuitId: {} for interface index {}.", circuitId, index);
310 continue;
311 }
312 String holdingTime = jsonNode1.path(IsisConstants.HOLDINGTIME).asText();
313 if (isPrimitive(holdingTime)) {
314 int input = Integer.parseInt(holdingTime);
315 if (input < 1 || input > 255) {
316 log.debug("Wrong holdingTime: {} for interface index {}.", holdingTime, index);
317 continue;
318 }
319 isisInterface.setHoldingTime(input);
320 } else {
321 log.debug("Wrong holdingTime: {} for interface index {}.", holdingTime, index);
322 continue;
323 }
324 String helloInterval = jsonNode1.path(IsisConstants.HELLOINTERVAL).asText();
325 if (isPrimitive(helloInterval)) {
326 int interval = Integer.parseInt(helloInterval);
327 if (interval > 0 && interval <= 255) {
328 isisInterface.setHelloInterval(interval);
329 } else {
330 log.debug("Wrong hello interval: {} for interface index {}.", helloInterval, index);
331 continue;
332 }
333 } else {
334 log.debug("Wrong hello interval: {} for interface index {}.", helloInterval, index);
335 continue;
336 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530337 interfaceList.add(isisInterface);
338 }
Jon Hallcbd1b392017-01-18 20:15:44 -0800339 if (!interfaceList.isEmpty()) {
sunish vk4b5ce002016-05-09 20:18:35 +0530340 IsisProcess process = new DefaultIsisProcess();
341 process.setProcessId(jsonNode.path(IsisConstants.PROCESSESID).asText());
342 process.setIsisInterfaceList(interfaceList);
343 isisProcessesList.add(process);
344 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530345 });
346
347 return isisProcessesList;
348 }
sunish vk4b5ce002016-05-09 20:18:35 +0530349
350 /**
351 * Returns interface MAC by index.
352 *
353 * @param interfaceIndex interface index
354 * @return interface IP by index
355 */
356 private MacAddress getInterfaceMac(int interfaceIndex) {
357 MacAddress macAddress = null;
358 try {
359 NetworkInterface networkInterface = NetworkInterface.getByIndex(interfaceIndex);
360 macAddress = MacAddress.valueOf(networkInterface.getHardwareAddress());
361 } catch (Exception e) {
362 log.debug("Error while getting Interface IP by index");
363 return macAddress;
364 }
365
366 return macAddress;
367 }
368
369 /**
370 * Returns interface IP by index.
371 *
372 * @param interfaceIndex interface index
373 * @return interface IP by index
374 */
375 private Ip4Address getInterfaceIp(int interfaceIndex) {
376 Ip4Address ipAddress = null;
377 try {
378 NetworkInterface networkInterface = NetworkInterface.getByIndex(interfaceIndex);
379 Enumeration ipAddresses = networkInterface.getInetAddresses();
380 while (ipAddresses.hasMoreElements()) {
381 InetAddress address = (InetAddress) ipAddresses.nextElement();
382 if (!address.isLinkLocalAddress()) {
383 ipAddress = Ip4Address.valueOf(address.getAddress());
384 break;
385 }
386 }
387 } catch (Exception e) {
388 log.debug("Error while getting Interface IP by index");
389 return IsisConstants.DEFAULTIP;
390 }
391 return ipAddress;
392 }
393
394 /**
395 * Returns interface MAC by index.
396 *
397 * @param interfaceIndex interface index
398 * @return interface IP by index
399 */
400 private String getInterfaceMask(int interfaceIndex) {
401 String subnetMask = null;
402 try {
403 Ip4Address ipAddress = getInterfaceIp(interfaceIndex);
404 NetworkInterface networkInterface = NetworkInterface.getByInetAddress(
405 InetAddress.getByName(ipAddress.toString()));
406 Enumeration ipAddresses = networkInterface.getInetAddresses();
407 int index = 0;
408 while (ipAddresses.hasMoreElements()) {
409 InetAddress address = (InetAddress) ipAddresses.nextElement();
410 if (!address.isLinkLocalAddress()) {
411 break;
412 }
413 index++;
414 }
415 int prfLen = networkInterface.getInterfaceAddresses().get(index).getNetworkPrefixLength();
416 int shft = 0xffffffff << (32 - prfLen);
417 int oct1 = ((byte) ((shft & 0xff000000) >> 24)) & 0xff;
418 int oct2 = ((byte) ((shft & 0x00ff0000) >> 16)) & 0xff;
419 int oct3 = ((byte) ((shft & 0x0000ff00) >> 8)) & 0xff;
420 int oct4 = ((byte) (shft & 0x000000ff)) & 0xff;
421 subnetMask = oct1 + "." + oct2 + "." + oct3 + "." + oct4;
422 } catch (Exception e) {
423 log.debug("Error while getting Interface network mask by index");
424 return subnetMask;
425 }
426 return subnetMask;
427 }
428
429 /**
430 * Checks if primitive or not.
431 *
432 * @param value input value
433 * @return true if number else false
434 */
435 private boolean isPrimitive(String value) {
436 boolean status = true;
437 value = value.trim();
438 if (value.length() < 1) {
439 return false;
440 }
441 for (int i = 0; i < value.length(); i++) {
442 char c = value.charAt(i);
443 if (!Character.isDigit(c)) {
444 status = false;
445 break;
446 }
447 }
448
449 return status;
450 }
451
452 /**
453 * Checks if system id is valid or not.
454 *
455 * @param value input value
456 * @return true if valid else false
457 */
458 private boolean isValidSystemId(String value) {
459 value = value.trim();
460 boolean status = true;
461 if (value.length() != 14) {
462 return false;
463 }
464 for (int i = 0; i < value.length(); i++) {
465 char c = value.charAt(i);
466 if (!Character.isDigit(c)) {
467 if (!((i == 4 || i == 9) && c == '.')) {
468 status = false;
469 break;
470 }
471 }
472 }
473
474 return status;
475 }
476
477 /**
478 * Disconnects the executor.
479 */
480 public void disconnectExecutor() {
481 if (connectExecutor != null) {
sunish vk7bdf4d42016-06-24 12:29:43 +0530482 future.cancel(true);
483 connectExecutor.shutdownNow();
sunish vk4b5ce002016-05-09 20:18:35 +0530484 connectExecutor = null;
485 }
486 }
487
488 /**
489 * Connects to peer.
490 */
491 public void connectPeer() {
492 scheduleConnectionRetry(this.connectRetryTime);
493 }
494
495 /**
496 * Retry connection with exponential back-off mechanism.
497 *
498 * @param retryDelay retry delay
499 */
500 private void scheduleConnectionRetry(long retryDelay) {
sunish vk7bdf4d42016-06-24 12:29:43 +0530501 if (connectExecutor == null) {
502 connectExecutor = Executors.newSingleThreadScheduledExecutor();
sunish vk4b5ce002016-05-09 20:18:35 +0530503 }
sunish vk7bdf4d42016-06-24 12:29:43 +0530504 future = connectExecutor.schedule(new ConnectionRetry(), retryDelay, TimeUnit.MINUTES);
505 }
506
507 /**
508 * Adds device details.
509 *
510 * @param isisRouter ISIS router instance
511 */
512 public void addDeviceDetails(IsisRouter isisRouter) {
513 agent.addConnectedRouter(isisRouter);
514 }
515
516 /**
517 * Removes device details.
518 *
519 * @param isisRouter Isis router instance
520 */
521 public void removeDeviceDetails(IsisRouter isisRouter) {
522 agent.removeConnectedRouter(isisRouter);
523 }
524
525 /**
526 * Adds link details.
527 *
528 * @param isisLink ISIS link instance
529 */
530 public void addLinkDetails(IsisLink isisLink) {
531 agent.addLink(isisLink);
532 }
533
534 /**
535 * Removes link details.
536 *
537 * @param isisLink ISIS link instance
538 */
539 public void removeLinkDetails(IsisLink isisLink) {
540 agent.deleteLink(isisLink);
541 }
542
543 /**
544 * Returns the isisAgent instance.
545 *
546 * @return agent
547 */
548 public IsisAgent agent() {
549 return this.agent;
sunish vk4b5ce002016-05-09 20:18:35 +0530550 }
551
552 /**
553 * Implements ISIS connection and manages connection to peer with back-off mechanism in case of failure.
554 */
555 class ConnectionRetry implements Runnable {
556 @Override
557 public void run() {
558 log.debug("Connect to peer {}", IsisConstants.SHOST);
559 initConnection();
sunish vkc3824e82016-05-11 19:38:24 +0530560 isisChannelHandler.sentConfigPacket(configPacket);
sunish vk4b5ce002016-05-09 20:18:35 +0530561 InetSocketAddress connectToSocket = new InetSocketAddress(IsisConstants.SHOST, isisPort.toInt());
562 try {
563 peerBootstrap.connect(connectToSocket).addListener(new ChannelFutureListener() {
564 @Override
565 public void operationComplete(ChannelFuture future) throws Exception {
566 if (!future.isSuccess()) {
567 connectRetryCounter++;
568 log.error("Connection failed, ConnectRetryCounter {} remote host {}", connectRetryCounter,
sunish vk7bdf4d42016-06-24 12:29:43 +0530569 IsisConstants.SHOST);
sunish vk4b5ce002016-05-09 20:18:35 +0530570 /*
571 * Reconnect to peer on failure is exponential till 4 mins, later on retry after every 4
572 * mins.
573 */
574 if (connectRetryTime < RETRY_INTERVAL) {
575 connectRetryTime = (connectRetryTime != 0) ? connectRetryTime * 2 : 1;
576 }
577 scheduleConnectionRetry(connectRetryTime);
578 } else {
sunish vkc3824e82016-05-11 19:38:24 +0530579 //Send the config packet
580 isisChannelHandler.sentConfigPacket(configPacket);
sunish vk4b5ce002016-05-09 20:18:35 +0530581 connectRetryCounter++;
582 log.info("Connected to remote host {}, Connect Counter {}", IsisConstants.SHOST,
sunish vk7bdf4d42016-06-24 12:29:43 +0530583 connectRetryCounter);
sunish vk4b5ce002016-05-09 20:18:35 +0530584 disconnectExecutor();
sunish vkc3824e82016-05-11 19:38:24 +0530585
sunish vk4b5ce002016-05-09 20:18:35 +0530586 return;
587 }
588 }
589 });
590 } catch (Exception e) {
591 log.info("Connect peer exception : " + e.toString());
592 disconnectExecutor();
593 }
594 }
595 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530596}