OSPF protocol manual merge from 1.6, due to cherry pick merge conflict
Change-Id: I93653e745468722ce95533537a79e897b4292f5d
diff --git a/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/Controller.java b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/Controller.java
index 3f8f967..cf24080 100644
--- a/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/Controller.java
+++ b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/Controller.java
@@ -15,13 +15,15 @@
*/
package org.onosproject.ospf.controller.impl;
-import org.jboss.netty.bootstrap.ServerBootstrap;
+import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.channel.AdaptiveReceiveBufferSizePredictor;
+import org.jboss.netty.channel.ChannelFuture;
+import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.FixedReceiveBufferSizePredictorFactory;
-import org.jboss.netty.channel.group.ChannelGroup;
-import org.jboss.netty.channel.group.DefaultChannelGroup;
-import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
+import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.TpPort;
import org.onosproject.net.driver.DriverService;
import org.onosproject.ospf.controller.OspfAgent;
import org.onosproject.ospf.controller.OspfArea;
@@ -29,42 +31,137 @@
import org.onosproject.ospf.controller.OspfLinkTed;
import org.onosproject.ospf.controller.OspfProcess;
import org.onosproject.ospf.controller.OspfRouter;
+import org.onosproject.ospf.protocol.util.OspfUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
-import java.net.SocketException;
-import java.util.ArrayList;
-import java.util.Collections;
import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Iterator;
import java.util.List;
-import java.util.Set;
-import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import static org.onlab.util.Tools.groupedThreads;
/**
- * Representation of the main controller class. Handles all setup and network listeners.
+ * Representation of an OSPF controller.
*/
public class Controller {
-
- protected static final Logger log = LoggerFactory.getLogger(Controller.class);
protected static final int BUFFER_SIZE = 4 * 1024 * 1024;
- private static final String PROCESS = "process";
- private static final String AREA = "area";
- private static final String INTERFACE = "interface";
-
- protected int ospfPort = 7000;
- protected int workerThreads = 16;
+ private static final Logger log = LoggerFactory.getLogger(Controller.class);
+ private static final int RETRY_INTERVAL = 4;
+ private final int peerWorkerThreads = 16;
protected long systemStartTime;
+ byte[] configPacket = null;
+ private List<OspfProcess> processes = null;
+ private OspfInterfaceChannelHandler ospfChannelHandler;
+ private NioClientSocketChannelFactory peerExecFactory;
+ private ClientBootstrap peerBootstrap = null;
+ private TpPort isisPort = TpPort.tpPort(OspfUtil.SPORT);
+ private ScheduledExecutorService connectExecutor = null;
+ private int connectRetryCounter = 0;
+ private int connectRetryTime;
private DriverService driverService;
private OspfAgent agent;
- private List<ChannelGroup> cgList = new ArrayList();
- private List<NioServerSocketChannelFactory> execFactoryLst = new ArrayList<>();
- private List<OspfProcess> processes;
+
+ /**
+ * Deactivates OSPF controller.
+ */
+ public void isisDeactivate() {
+ peerExecFactory.shutdown();
+ }
+
+ /**
+ * Updates the processes configuration.
+ *
+ * @param ospfProcesses list of OSPF process instances
+ * @throws Exception might throws parse exception
+ */
+ public void updateConfig(List<OspfProcess> ospfProcesses) throws Exception {
+ log.debug("Controller::UpdateConfig called");
+ configPacket = new byte[OspfUtil.CONFIG_LENGTH];
+ byte numberOfInterface = 0; // number of interfaces to configure
+ configPacket[0] = (byte) 0xFF; // its a conf packet - identifier
+ for (OspfProcess ospfProcess : ospfProcesses) {
+ log.debug("OspfProcessDetails : " + ospfProcess);
+ for (OspfArea ospfArea : ospfProcess.areas()) {
+ for (OspfInterface ospfInterface : ospfArea.ospfInterfaceList()) {
+ log.debug("OspfInterfaceDetails : " + ospfInterface);
+ numberOfInterface++;
+ configPacket[2 * numberOfInterface] = (byte) ospfInterface.interfaceIndex();
+ configPacket[(2 * numberOfInterface) + 1] = (byte) 4;
+ }
+ }
+ }
+ configPacket[1] = numberOfInterface;
+ //First time configuration
+ if (processes == null) {
+ if (ospfProcesses.size() > 0) {
+ processes = ospfProcesses;
+ connectPeer();
+ }
+ } else {
+ ospfChannelHandler.updateInterfaceMap(ospfProcesses);
+ //Send the config packet
+ ospfChannelHandler.sentConfigPacket(configPacket);
+ }
+ }
+
+ /**
+ * Initializes the netty client channel connection.
+ */
+ private void initConnection() {
+ if (peerBootstrap != null) {
+ return;
+ }
+ peerBootstrap = createPeerBootStrap();
+
+ peerBootstrap.setOption("reuseAddress", true);
+ peerBootstrap.setOption("tcpNoDelay", true);
+ peerBootstrap.setOption("keepAlive", true);
+ peerBootstrap.setOption("receiveBufferSize", Controller.BUFFER_SIZE);
+ peerBootstrap.setOption("receiveBufferSizePredictorFactory",
+ new FixedReceiveBufferSizePredictorFactory(
+ Controller.BUFFER_SIZE));
+ peerBootstrap.setOption("receiveBufferSizePredictor",
+ new AdaptiveReceiveBufferSizePredictor(64, 4096, 65536));
+ peerBootstrap.setOption("child.keepAlive", true);
+ peerBootstrap.setOption("child.tcpNoDelay", true);
+ peerBootstrap.setOption("child.sendBufferSize", Controller.BUFFER_SIZE);
+ peerBootstrap.setOption("child.receiveBufferSize", Controller.BUFFER_SIZE);
+ peerBootstrap.setOption("child.receiveBufferSizePredictorFactory",
+ new FixedReceiveBufferSizePredictorFactory(
+ Controller.BUFFER_SIZE));
+ peerBootstrap.setOption("child.reuseAddress", true);
+
+ ospfChannelHandler = new OspfInterfaceChannelHandler(this, processes);
+ ChannelPipelineFactory pfact = new OspfPipelineFactory(ospfChannelHandler);
+ peerBootstrap.setPipelineFactory(pfact);
+ }
+
+ /**
+ * Creates peer boot strap.
+ *
+ * @return client bootstrap instance
+ */
+ private ClientBootstrap createPeerBootStrap() {
+
+ if (peerWorkerThreads == 0) {
+ peerExecFactory = new NioClientSocketChannelFactory(
+ Executors.newCachedThreadPool(groupedThreads("onos/isis", "boss-%d")),
+ Executors.newCachedThreadPool(groupedThreads("onos/isis", "worker-%d")));
+ return new ClientBootstrap(peerExecFactory);
+ } else {
+ peerExecFactory = new NioClientSocketChannelFactory(
+ Executors.newCachedThreadPool(groupedThreads("onos/isis", "boss-%d")),
+ Executors.newCachedThreadPool(groupedThreads("onos/isis", "worker-%d")),
+ peerWorkerThreads);
+ return new ClientBootstrap(peerExecFactory);
+ }
+ }
/**
* Gets all configured processes.
@@ -106,36 +203,14 @@
/**
* Removes link details.
*
- * @param ospfRouter OSPF router instance
+ * @param ospfRouter OSPF router instance
+ * @param ospfLinkTed OSPF link ted instance
*/
- public void removeLinkDetails(OspfRouter ospfRouter) {
- agent.deleteLink(ospfRouter);
+ public void removeLinkDetails(OspfRouter ospfRouter, OspfLinkTed ospfLinkTed) {
+ agent.deleteLink(ospfRouter, ospfLinkTed);
}
/**
- * Creates a server bootstrap.
- *
- * @return ServerBootstrap bootstrap instance
- */
- private ServerBootstrap createServerBootStrap() {
-
- Executor bossPool = Executors.newCachedThreadPool();
- Executor workerPool = Executors.newCachedThreadPool();
- NioServerSocketChannelFactory executerFactory;
-
- if (workerThreads == 0) {
- executerFactory = new NioServerSocketChannelFactory(bossPool, workerPool);
- execFactoryLst.add(executerFactory);
- } else {
- executerFactory = new NioServerSocketChannelFactory(bossPool, workerPool, workerThreads);
- execFactoryLst.add(executerFactory);
- }
-
- return new ServerBootstrap(executerFactory);
- }
-
-
- /**
* Initializes internal data structures.
*/
public void init() {
@@ -149,7 +224,7 @@
* @param driverService driver service instance
*/
public void start(OspfAgent ag, DriverService driverService) {
- log.info("Starting OSPF Controller...!!!");
+ log.info("Starting OSPF controller...!!!");
this.agent = ag;
this.driverService = driverService;
this.init();
@@ -159,615 +234,143 @@
* Stops the Controller.
*/
public void stop() {
- log.info("Stopping OSPF Controller...!!!");
-
- for (ChannelGroup cg : cgList) {
- cg.close();
- }
-
- for (NioServerSocketChannelFactory execFactory : execFactoryLst) {
- execFactory.shutdown();
- }
-
+ log.info("Stopping OSPF controller...!!!");
+ isisDeactivate();
processes.clear();
}
/**
- * Deletes configured interface from the area.
+ * Returns interface IP by index.
*
- * @param processId process id
- * @param areaId area id
- * @param interfaceToDelete interface to delete
- * @return true if operation success else false
+ * @param interfaceIndex interface index
+ * @return interface IP by index
*/
- public boolean deleteInterfaceFromArea(String processId, String areaId, String interfaceToDelete) {
- Iterator<OspfProcess> processItr = processes.iterator();
-
- while (processItr.hasNext()) {
- OspfProcess process = processItr.next();
- if (processId.equalsIgnoreCase(process.processId())) {
- Iterator<OspfArea> areaItr = process.areas().iterator();
- while (areaItr.hasNext()) {
- OspfArea area = areaItr.next();
- Iterator<OspfInterface> ospfIntrItr = area.getInterfacesLst().iterator();
- if (area.areaId().toString().equalsIgnoreCase(areaId)) {
- while (ospfIntrItr.hasNext()) {
- OspfInterface ospfIntr = ospfIntrItr.next();
- if (interfaceToDelete.equalsIgnoreCase(ospfIntr.ipAddress().toString())) {
- ospfIntrItr.remove();
- log.debug("Interface With Id {} is removed from Area {}",
- ospfIntr.ipAddress(), ospfIntr.areaId());
- return true;
- }
- }
- }
- }
- }
- }
-
- return false;
- }
-
- /*
- * Checks area with area id exists in process.
- *
- * @param processId process id
- * @param areaId area id
- * @return true if exist else false
- */
- public boolean checkArea(String processId, String areaId) {
- for (OspfProcess process : processes) {
- if (processId.equalsIgnoreCase(process.processId())) {
- for (OspfArea area : process.areas()) {
- if (area.areaId().toString().equalsIgnoreCase(areaId)) {
- return true;
- }
- }
- }
- }
- return false;
- }
-
- /*
- * Checks process with process id exists or not.
- *
- * @param processId process id
- * @return true if exist else false
- */
- public boolean checkProcess(String processId) {
- log.debug("CheckProcess,Process Id ={} processes={}", processId, processes);
- for (OspfProcess process : processes) {
- if (processId.equalsIgnoreCase(process.processId())) {
- return true;
- }
- }
- return false;
- }
-
- /*
- * Checks interface exists in given area.
- *
- * @param processId process id
- * @param areaId area id
- * @param ipAddress interface
- * @return true if exist else false
- */
- public boolean checkInterface(String processId, String areaId, String interfaceIp) {
- for (OspfProcess process : processes) {
- if (processId.equalsIgnoreCase(process.processId())) {
- for (OspfArea area : process.areas()) {
- if (area.areaId().toString().equalsIgnoreCase(areaId)) {
- for (OspfInterface ospfInterface : area.getInterfacesLst()) {
- if (ospfInterface.ipAddress().toString().equalsIgnoreCase(interfaceIp)) {
- return true;
- }
- }
- }
- }
- }
- }
- return false;
- }
-
- /**
- * Create processes first time when no process exist.
- * Create server bootstraps for all the interfaces in the processes.
- *
- * @param ospfProcesses list of OSPF processes to create
- */
- private void createProcessWhenNoProcessesExists(List<OspfProcess> ospfProcesses) {
- Set<String> interfaceIpList = new HashSet<>();
- Set<String> areaIdList = new HashSet<>();
- if (processes != null) {
- if (processes.size() == 0) {
-
- processes.addAll(ospfProcesses);
- for (OspfProcess process : ospfProcesses) {
- for (OspfArea area : process.areas()) {
- areaIdList.add(area.areaId().toString());
- for (OspfInterface intrfc : area.getInterfacesLst()) {
- interfaceIpList.add(intrfc.ipAddress().toString());
- }
- }
- }
- createBootStrapForCreatedInterface(interfaceIpList, areaIdList);
- }
- } else {
- processes = new ArrayList<>();
- processes.addAll(ospfProcesses);
-
- for (OspfProcess process : ospfProcesses) {
- for (OspfArea area : process.areas()) {
- areaIdList.add(area.areaId().toString());
- for (OspfInterface intrfc : area.getInterfacesLst()) {
- interfaceIpList.add(intrfc.ipAddress().toString());
- }
- }
- }
- createBootStrapForCreatedInterface(interfaceIpList, areaIdList);
- }
- }
-
- /**
- * Creates processes when already process exist.
- * It can be modifying existing process or adding a new process.
- *
- * @param ospfProcesses list of processes
- */
- private void createProcessWhenProcessesExists(List<OspfProcess> ospfProcesses) {
- if (ospfProcesses != null) {
- for (OspfProcess process : ospfProcesses) {
- if (!checkProcess(process.processId())) {
- createNewProcess(process.processId(), process);
- } else {
- List<OspfArea> areas = process.areas();
- for (OspfArea area : areas) {
- if (!checkArea(process.processId(), area.areaId().toString())) {
- createAreaInProcess(process.processId(),
- area.areaId().toString(), area);
- } else {
- updateAreaInProcess(process.processId(), area.areaId().toString(), area);
- for (OspfInterface interfc : area.getInterfacesLst()) {
- if (!checkInterface(process.processId(),
- area.areaId().toString(), interfc.ipAddress().toString())) {
- createInterfaceInAreaInProcess(process.processId(),
- area.areaId().toString(), interfc);
- } else {
- updateInterfaceParameters(process.processId(),
- area.areaId().toString(),
- interfc.ipAddress().toString(), interfc);
- }
- }
- }
- }
- }
- }
- }
- }
-
- /**
- * Updates the area information in already started OSPF processes.
- *
- * @param processId process id
- * @param areaId area id
- * @param areaFrmConfig area to update
- */
- public void updateAreaInProcess(String processId, String areaId, OspfArea areaFrmConfig) {
- if (processes != null) {
- Iterator<OspfProcess> processItr = processes.iterator();
- while (processItr.hasNext()) {
- OspfProcess process = processItr.next();
- if (processId.equalsIgnoreCase(process.processId())) {
- Iterator<OspfArea> area = process.areas().iterator();
- while (area.hasNext()) {
- OspfArea ospfArea = area.next();
- if (areaId.equalsIgnoreCase(ospfArea.areaId().toString())) {
- ospfArea.setAddressRanges(areaFrmConfig.addressRanges());
- ospfArea.setRouterId(areaFrmConfig.routerId());
- ospfArea.setTransitCapability(areaFrmConfig.isTransitCapability());
- ospfArea.setExternalRoutingCapability(areaFrmConfig.isExternalRoutingCapability());
- ospfArea.setStubCost(areaFrmConfig.stubCost());
- ospfArea.setOptions(areaFrmConfig.options());
- ospfArea.setIsOpaqueEnabled(areaFrmConfig.isOpaqueEnabled());
- log.debug("updateAreaInProcess::Process Id::{}::Ospf Area with Id::{}::is " +
- "updated", processId, areaId);
- }
- }
- }
- }
- }
- }
-
- /**
- * Updates the processes configuration.
- *
- * @param ospfProcesses list of OSPF processes
- */
- public void updateConfig(List<OspfProcess> ospfProcesses) {
- log.info("Controller::UpdateConfig called");
- if (processes != null) {
- if (processes.size() == 0) {
- createProcessWhenNoProcessesExists(ospfProcesses);
- } else {
- createProcessWhenProcessesExists(ospfProcesses);
- }
- } else {
- createProcessWhenNoProcessesExists(ospfProcesses);
- }
- }
-
- /**
- * Deletes configuration.
- *
- * @param ospfProcesses OSPF processes
- * @param attribute attribute to delete
- */
- public void deleteConfig(List<OspfProcess> ospfProcesses, String attribute) {
- log.info("Controller::UpdateConfig called");
- if (processes != null) {
- if (processes.size() == 0) {
- log.debug("DeleteConfig:: No process exists");
- } else {
- deleteProcessWhenExists(ospfProcesses, attribute);
- }
- } else {
- log.debug("DeleteConfig:: No process exists");
- }
- }
-
- /**
- * Creates a new process.
- *
- * @param processId process id
- * @param process OSPF process instance
- */
- private void createNewProcess(String processId, OspfProcess process) {
- Set<String> interfaceIpList = new HashSet<>();
- Set<String> areaIdList = new HashSet<>();
-
- processes.add(process);
- for (OspfArea area : process.areas()) {
- areaIdList.add(area.areaId().toString());
- for (OspfInterface interfc : area.getInterfacesLst()) {
- interfaceIpList.add(interfc.ipAddress().toString());
- }
- }
- log.debug("createNewProcess::List of areas in process::{} areas::{}", processId, areaIdList);
-
- createBootStrapForCreatedInterface(interfaceIpList, areaIdList);
-
- log.debug("createNewProcess:: all processes::{}", processes);
- }
-
- /**
- * Creates a new area information in the process.
- *
- * @param processId process id
- * @param areaId area id
- * @param area OSPF area instance
- */
- private void createAreaInProcess(String processId, String areaId, OspfArea area) {
- Set<String> interfaceIpList = new HashSet<>();
- Set<String> areaIdList = new HashSet<>();
-
- Iterator<OspfProcess> processItr = processes.iterator();
- while (processItr.hasNext()) {
- OspfProcess process = processItr.next();
- List<OspfArea> areasInProcess = process.areas();
- if (processId.equalsIgnoreCase(process.processId())) {
- areasInProcess.add(area);
-
- for (OspfInterface intrfc : area.getInterfacesLst()) {
- interfaceIpList.add(intrfc.ipAddress().toString());
- }
- areaIdList.add(area.areaId().toString());
- log.debug("createAreaInProcess::List of areas in process Id::{} " +
- "AreaId ::{} update process::{}",
- processId, areaId, process);
- }
- }
- createBootStrapForCreatedInterface(interfaceIpList, areaIdList);
- log.debug("createAreaInProcess:: all processes::{}", processes);
- }
-
- /**
- * Creates an interface in the given area and process.
- *
- * @param processId process id
- * @param areaId area id
- * @param ospfInterface OSPF interface instance
- */
- private void createInterfaceInAreaInProcess(String processId,
- String areaId, OspfInterface ospfInterface) {
- Set<String> interfaceIpList = new HashSet<>();
- Set<String> areaIdList = new HashSet<>();
-
- Iterator<OspfProcess> processItr = processes.iterator();
- while (processItr.hasNext()) {
- OspfProcess process = processItr.next();
- List<OspfArea> areasInProcess = process.areas();
- if (processId.equalsIgnoreCase(process.processId())) {
- Iterator<OspfArea> areaItr = areasInProcess.iterator();
- while (areaItr.hasNext()) {
- OspfArea area = areaItr.next();
- if (areaId.equalsIgnoreCase(area.areaId().toString())) {
- area.getInterfacesLst().add(ospfInterface);
- interfaceIpList.add(ospfInterface.ipAddress().toString());
-
- log.debug("createInterfaceInAreaInProcess::Interface " +
- "updated in process Id::{} AreaId ::{} Interface List{}",
- processId, areaId, area.getInterfacesLst());
-
- }
- }
- }
- }
- createBootStrapForCreatedInterface(interfaceIpList, areaIdList);
- log.debug("createInterfaceInAreaInProcess:: all processes::{}", processes);
- }
-
- /**
- * Updates interface parameters.
- *
- * @param processId process id
- * @param areaId area id
- * @param interfaceId interface id
- * @param ospfInterface OSPF interface instance
- */
- private void updateInterfaceParameters(String processId, String areaId, String interfaceId,
- OspfInterface ospfInterface) {
- Iterator<OspfProcess> processItr = processes.iterator();
- while (processItr.hasNext()) {
- OspfProcess process = processItr.next();
- if (processId.equalsIgnoreCase(process.processId())) {
- Iterator<OspfArea> areItr = process.areas().iterator();
- while (areItr.hasNext()) {
- OspfArea area = (OspfArea) areItr.next();
- if (area.areaId().toString().equalsIgnoreCase(areaId)) {
- Iterator<OspfInterface> intfcList = area.getInterfacesLst().iterator();
- while (intfcList.hasNext()) {
- OspfInterface intrfcObj = intfcList.next();
- if (interfaceId.equalsIgnoreCase(intrfcObj.ipAddress().toString())) {
- intrfcObj.setPollInterval(ospfInterface.pollInterval());
- intrfcObj.setTransmitDelay(ospfInterface.transmitDelay());
- intrfcObj.setBdr(ospfInterface.bdr());
- intrfcObj.setDr(ospfInterface.dr());
- intrfcObj.setAuthKey(ospfInterface.authKey());
- intrfcObj.setAuthType(ospfInterface.authType());
- intrfcObj.setHelloIntervalTime(ospfInterface.helloIntervalTime());
- intrfcObj.setReTransmitInterval(ospfInterface.reTransmitInterval());
- intrfcObj.setMtu(ospfInterface.mtu());
- intrfcObj.setInterfaceCost(ospfInterface.interfaceCost());
- intrfcObj.setInterfaceType(ospfInterface.interfaceType());
- intrfcObj.setRouterDeadIntervalTime(ospfInterface.routerDeadIntervalTime());
- intrfcObj.setRouterPriority(ospfInterface.routerPriority());
- intrfcObj.setIpNetworkMask(ospfInterface.ipNetworkMask());
- log.debug("updateInterfaceParameters::Interface updated in " +
- "process Id::{} AreaId ::{} Interface Id:{} " +
- "Updated Interface List: {}", processId, areaId,
- interfaceId, intfcList);
- }
- }
- }
- }
- }
- }
- log.debug("updateInterfaceParameters:: all processes::{}", processes);
- }
-
- /**
- * Creates server bootstrap for interface.
- *
- * @param interfaceIPs set of interfaces
- * @param areaIds set of area id's
- */
- private void createBootStrapForCreatedInterface(Set<String> interfaceIPs, Set<String> areaIds) {
-
- log.debug("createBootStrapForCreatedInterface:: List of new Interfaces::{}, " +
- "List of new areas::{}", interfaceIPs, areaIds);
- List<String> networkInterfaces = new ArrayList();
- //get the connected interfaces
- Enumeration<NetworkInterface> nets = null;
+ private Ip4Address getInterfaceIp(int interfaceIndex) {
+ Ip4Address ipAddress = null;
try {
- nets = NetworkInterface.getNetworkInterfaces();
- // Check NetworkInterfaces and add the IP's
- for (NetworkInterface netInt : Collections.list(nets)) {
- // if the interface is up & not loopback
- if (!netInt.isUp() && !netInt.isLoopback()) {
- continue;
- }
- //get all the InetAddresses
- Enumeration<InetAddress> inetAddresses = netInt.getInetAddresses();
- for (InetAddress inetAddress : Collections.list(inetAddresses)) {
- String ipAddress = inetAddress.getHostAddress();
- networkInterfaces.add(ipAddress);
+ NetworkInterface networkInterface = NetworkInterface.getByIndex(interfaceIndex);
+ Enumeration ipAddresses = networkInterface.getInetAddresses();
+ while (ipAddresses.hasMoreElements()) {
+ InetAddress address = (InetAddress) ipAddresses.nextElement();
+ if (!address.isLinkLocalAddress()) {
+ ipAddress = Ip4Address.valueOf(address.getAddress());
+ break;
}
}
- //Search for the address in all configured areas interfaces
- for (OspfProcess process : processes) {
- for (OspfArea area : process.areas()) {
- for (OspfInterface ospfIf : area.getInterfacesLst()) {
- String ipFromConfig = ospfIf.ipAddress().toString();
- if (interfaceIPs.contains(ipFromConfig)) {
- log.debug("Ip address::{} for area {} is newly created" + ipFromConfig);
- if (networkInterfaces.contains(ipFromConfig)) {
- log.debug("Both Config and Interface have ipAddress {} for area {}",
- ipFromConfig, area.areaId());
- // if same IP address create
- try {
- log.debug("Creating ServerBootstrap for {} @ {}", ipFromConfig, ospfPort);
+ } catch (Exception e) {
+ log.debug("Error while getting Interface IP by index");
+ return OspfUtil.DEFAULTIP;
+ }
- final ServerBootstrap bootstrap = createServerBootStrap();
+ return ipAddress;
+ }
- bootstrap.setOption("receiveBufferSize", Controller.BUFFER_SIZE);
- bootstrap.setOption("receiveBufferSizePredictorFactory",
- new FixedReceiveBufferSizePredictorFactory(
- Controller.BUFFER_SIZE));
- bootstrap.setOption("reuseAddress", true);
- bootstrap.setOption("tcpNoDelay", true);
- bootstrap.setOption("keepAlive", true);
+ /**
+ * Returns interface mask by index.
+ *
+ * @param interfaceIndex interface index
+ * @return interface IP by index
+ */
+ private String getInterfaceMask(int interfaceIndex) {
+ String subnetMask = null;
+ try {
+ Ip4Address ipAddress = getInterfaceIp(interfaceIndex);
+ NetworkInterface networkInterface = NetworkInterface.getByInetAddress(
+ InetAddress.getByName(ipAddress.toString()));
+ Enumeration ipAddresses = networkInterface.getInetAddresses();
+ int index = 0;
+ while (ipAddresses.hasMoreElements()) {
+ InetAddress address = (InetAddress) ipAddresses.nextElement();
+ if (!address.isLinkLocalAddress()) {
+ break;
+ }
+ index++;
+ }
+ int prfLen = networkInterface.getInterfaceAddresses().get(index).getNetworkPrefixLength();
+ int shft = 0xffffffff << (32 - prfLen);
+ int oct1 = ((byte) ((shft & 0xff000000) >> 24)) & 0xff;
+ int oct2 = ((byte) ((shft & 0x00ff0000) >> 16)) & 0xff;
+ int oct3 = ((byte) ((shft & 0x0000ff00) >> 8)) & 0xff;
+ int oct4 = ((byte) (shft & 0x000000ff)) & 0xff;
+ subnetMask = oct1 + "." + oct2 + "." + oct3 + "." + oct4;
+ } catch (Exception e) {
+ log.debug("Error while getting Interface network mask by index");
+ return subnetMask;
+ }
- bootstrap.setOption("child.receiveBufferSize", Controller.BUFFER_SIZE);
- bootstrap.setOption("child.receiveBufferSizePredictorFactory",
- new FixedReceiveBufferSizePredictorFactory(
- Controller.BUFFER_SIZE));
- bootstrap.setOption("child.reuseAddress", true);
- bootstrap.setOption("child.tcpNoDelay", true);
- bootstrap.setOption("child.keepAlive", true);
- bootstrap.setOption("receiveBufferSizePredictorFactory",
- new FixedReceiveBufferSizePredictorFactory(
- Controller.BUFFER_SIZE));
- bootstrap.setOption("receiveBufferSizePredictor",
- new AdaptiveReceiveBufferSizePredictor(64, 1024, 65536));
+ return subnetMask;
+ }
- ChannelPipelineFactory pfact = new OspfPipelineFactory(this, area, ospfIf);
- bootstrap.setPipelineFactory(pfact);
- InetSocketAddress sa = new InetSocketAddress(InetAddress.getByName(ipFromConfig),
- ospfPort);
+ /**
+ * Disconnects the executor.
+ */
+ public void disconnectExecutor() {
+ if (connectExecutor != null) {
+ connectExecutor.shutdown();
+ connectExecutor = null;
+ }
+ }
- ChannelGroup cg = new DefaultChannelGroup();
- cg.add(bootstrap.bind(sa));
- cgList.add(cg);
+ /**
+ * Connects to peer.
+ */
+ public void connectPeer() {
+ scheduleConnectionRetry(this.connectRetryTime);
+ }
- log.debug("Listening for connections on {}", sa);
+ /**
+ * Retry connection with exponential back-off mechanism.
+ *
+ * @param retryDelay retry delay
+ */
+ private void scheduleConnectionRetry(long retryDelay) {
+ if (this.connectExecutor == null) {
+ this.connectExecutor = Executors.newSingleThreadScheduledExecutor();
+ }
+ this.connectExecutor.schedule(new ConnectionRetry(), retryDelay, TimeUnit.MINUTES);
+ }
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
+ /**
+ * Implements ISIS connection and manages connection to peer with back-off mechanism in case of failure.
+ */
+ class ConnectionRetry implements Runnable {
+ @Override
+ public void run() {
+ log.debug("Connect to peer {}", OspfUtil.SHOST);
+ initConnection();
+ ospfChannelHandler.sentConfigPacket(configPacket);
+ InetSocketAddress connectToSocket = new InetSocketAddress(OspfUtil.SHOST, isisPort.toInt());
+ try {
+ peerBootstrap.connect(connectToSocket).addListener(new ChannelFutureListener() {
+ @Override
+ public void operationComplete(ChannelFuture future) throws Exception {
+ if (!future.isSuccess()) {
+ connectRetryCounter++;
+ log.error("Connection failed, ConnectRetryCounter {} remote host {}", connectRetryCounter,
+ OspfUtil.SHOST);
+ /*
+ * Reconnect to peer on failure is exponential till 4 mins, later on retry after every 4
+ * mins.
+ */
+ if (connectRetryTime < RETRY_INTERVAL) {
+ connectRetryTime = (connectRetryTime != 0) ? connectRetryTime * 2 : 1;
}
+ scheduleConnectionRetry(connectRetryTime);
} else {
- log.debug("Ip address::{} for area {} is not newly created" + ipFromConfig);
+ //Send the config packet
+ ospfChannelHandler.sentConfigPacket(configPacket);
+ connectRetryCounter++;
+ log.info("Connected to remote host {}, Connect Counter {}", OspfUtil.SHOST,
+ connectRetryCounter);
+ disconnectExecutor();
+
+ return;
}
}
- if (areaIds.contains(area.areaId().toString())) {
- area.initializeDb();
- }
- }
- }
-
- } catch (SocketException e) {
- log.error("Error occured due to SocketException::Class::{},Line::{},Method::{}",
- e.getStackTrace()[0].getFileName(), e.getStackTrace()[0].getLineNumber(),
- e.getStackTrace()[0].getMethodName());
- }
- }
-
- /**
- * Deletes given process.
- *
- * @param ospfProcesses list of OSPF process instance.
- * @param attribute attribute to delete
- */
- public void deleteProcessWhenExists(List<OspfProcess> ospfProcesses, String attribute) {
- if (ospfProcesses != null) {
- for (OspfProcess process : ospfProcesses) {
- if (checkProcess(process.processId())) {
- if (PROCESS.equalsIgnoreCase(attribute)) {
- deleteProcess(process.processId(), process);
- } else {
- List<OspfArea> areas = process.areas();
- for (OspfArea area : areas) {
- if (checkArea(process.processId(), area.areaId().toString())) {
- if (AREA.equalsIgnoreCase(attribute)) {
- deleteAreaFromProcess(process.processId(),
- area.areaId().toString(), area);
- } else {
- for (OspfInterface interfc : area.getInterfacesLst()) {
- if (checkInterface(process.processId(),
- area.areaId().toString(),
- interfc.ipAddress().toString())) {
- if (INTERFACE.equalsIgnoreCase(attribute)) {
- deleteInterfaceFromAreaProcess(process.processId(),
- area.areaId().toString(),
- interfc);
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
-
- /**
- * Deletes given process.
- *
- * @param processId process id
- * @param process OSPF process instance
- */
- private void deleteProcess(String processId, OspfProcess process) {
- if (processes != null) {
- Iterator<OspfProcess> itrProcess = processes.iterator();
- while (itrProcess.hasNext()) {
- OspfProcess ospfPrs = itrProcess.next();
- if (processId.equalsIgnoreCase(ospfPrs.processId())) {
- itrProcess.remove();
- }
- }
- }
- }
-
- /**
- * Deletes area from process.
- *
- * @param processId process id
- * @param areaId area id
- * @param area OSPF area instance
- */
- private void deleteAreaFromProcess(String processId, String areaId, OspfArea area) {
- if (processes != null) {
- Iterator<OspfProcess> itrProcess = processes.iterator();
- while (itrProcess.hasNext()) {
- OspfProcess ospfPrs = itrProcess.next();
- if (processId.equalsIgnoreCase(ospfPrs.processId())) {
- if (ospfPrs.areas() != null) {
- Iterator<OspfArea> itrArea = ospfPrs.areas().iterator();
- while (itrArea.hasNext()) {
- OspfArea ospfArea = itrArea.next();
- if (areaId.equalsIgnoreCase(ospfArea.areaId().toString())) {
- itrArea.remove();
- }
- }
- }
- }
- }
- }
- }
-
- /**
- * Deletes interface from area.
- *
- * @param processId process id
- * @param areaId area id
- * @param interfaceToDelete interface to delete
- */
- private void deleteInterfaceFromAreaProcess(String processId, String areaId, OspfInterface interfaceToDelete) {
- if (processes != null) {
- Iterator<OspfProcess> itrProcess = processes.iterator();
- while (itrProcess.hasNext()) {
- OspfProcess ospfPrs = itrProcess.next();
- if (processId.equalsIgnoreCase(ospfPrs.processId())) {
- if (ospfPrs.areas() != null) {
- Iterator<OspfArea> itrArea = ospfPrs.areas().iterator();
- while (itrArea.hasNext()) {
- OspfArea ospfArea = itrArea.next();
- if (areaId.equalsIgnoreCase(ospfArea.areaId().toString())) {
- if (ospfArea.getInterfacesLst() != null) {
- Iterator<OspfInterface> intrfcList = ospfArea.getInterfacesLst().iterator();
- while (intrfcList.hasNext()) {
- OspfInterface ospfItrfc = intrfcList.next();
- if (interfaceToDelete.ipAddress().equals(ospfItrfc.ipAddress())) {
- intrfcList.remove();
- }
- }
- }
- }
- }
- }
- }
+ });
+ } catch (Exception e) {
+ log.info("Connect peer exception : " + e.toString());
+ disconnectExecutor();
}
}
}