blob: 5ac63b14e8927ffa62aa206f01f3c405158121f5 [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 */
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +053016package org.onosproject.ospf.controller.impl;
17
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +053018import org.jboss.netty.channel.Channel;
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +053019import org.jboss.netty.channel.ChannelHandlerContext;
20import org.jboss.netty.channel.ChannelStateEvent;
21import org.jboss.netty.channel.ExceptionEvent;
22import org.jboss.netty.channel.MessageEvent;
23import org.jboss.netty.handler.timeout.IdleStateAwareChannelHandler;
24import org.jboss.netty.handler.timeout.ReadTimeoutException;
25import org.onlab.packet.Ip4Address;
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +053026import org.onosproject.ospf.controller.OspfArea;
27import org.onosproject.ospf.controller.OspfInterface;
sunishvkf7c56552016-07-18 16:02:39 +053028import org.onosproject.ospf.controller.OspfMessage;
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +053029import org.onosproject.ospf.controller.OspfNbr;
sunishvkf7c56552016-07-18 16:02:39 +053030import org.onosproject.ospf.controller.OspfProcess;
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +053031import org.onosproject.ospf.controller.area.OspfInterfaceImpl;
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +053032import org.onosproject.ospf.controller.util.OspfInterfaceType;
33import org.onosproject.ospf.exceptions.OspfParseException;
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +053034import org.onosproject.ospf.protocol.util.OspfInterfaceState;
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +053035import org.slf4j.Logger;
36import org.slf4j.LoggerFactory;
37
38import java.io.IOException;
39import java.nio.channels.ClosedChannelException;
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +053040import java.util.List;
sunishvkf7c56552016-07-18 16:02:39 +053041import java.util.Map;
42import java.util.concurrent.ConcurrentHashMap;
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +053043import java.util.concurrent.RejectedExecutionException;
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +053044
45/**
46 * Channel handler deals with the OSPF channel connection.
sunishvkf7c56552016-07-18 16:02:39 +053047 * Also it dispatches messages to the appropriate handlers for processing.
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +053048 */
49public class OspfInterfaceChannelHandler extends IdleStateAwareChannelHandler {
50
sunishvkf7c56552016-07-18 16:02:39 +053051 private static final Logger log = LoggerFactory.getLogger(OspfInterfaceChannelHandler.class);
52 private static Map<Integer, Object> isisDb = null;
53 private Channel channel = null;
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +053054 private Controller controller;
sunishvkf7c56552016-07-18 16:02:39 +053055 private List<OspfProcess> processes = null;
56 private byte[] configPacket = null;
57 private Map<Integer, OspfInterface> ospfInterfaceMap = new ConcurrentHashMap<>();
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +053058
59 /**
60 * Creates an instance of OSPF channel handler.
61 *
sunishvkf7c56552016-07-18 16:02:39 +053062 * @param controller controller instance
63 * @param processes list of configured processes
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +053064 */
sunishvkf7c56552016-07-18 16:02:39 +053065 public OspfInterfaceChannelHandler(Controller controller, List<OspfProcess> processes) {
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +053066 this.controller = controller;
sunishvkf7c56552016-07-18 16:02:39 +053067 this.processes = processes;
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +053068 }
69
70 /**
sunishvkf7c56552016-07-18 16:02:39 +053071 * Initializes the interface map with interface details.
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +053072 */
Ray Milkey019fba42018-01-31 14:07:47 -080073 public void initializeInterfaceMap() {
sunishvkf7c56552016-07-18 16:02:39 +053074 for (OspfProcess process : processes) {
75 for (OspfArea area : process.areas()) {
76 for (OspfInterface ospfInterface : area.ospfInterfaceList()) {
77 OspfInterface anInterface = ospfInterfaceMap.get(ospfInterface.interfaceIndex());
78 if (anInterface == null) {
79 ospfInterface.setOspfArea(area);
80 ((OspfInterfaceImpl) ospfInterface).setController(controller);
81 ((OspfInterfaceImpl) ospfInterface).setState(OspfInterfaceState.DOWN);
82 ospfInterface.setDr(Ip4Address.valueOf("0.0.0.0"));
83 ospfInterface.setBdr(Ip4Address.valueOf("0.0.0.0"));
84 ospfInterfaceMap.put(ospfInterface.interfaceIndex(), ospfInterface);
85 }
86 ((OspfInterfaceImpl) ospfInterface).setChannel(channel);
87 ospfInterface.interfaceUp();
88 ospfInterface.startDelayedAckTimer();
89 }
90 //Initialize the LSDB and aging process
91 area.initializeDb();
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +053092 }
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +053093 }
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +053094 }
95
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +053096 /**
sunishvkf7c56552016-07-18 16:02:39 +053097 * Updates the interface map with interface details.
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +053098 *
sunishvkf7c56552016-07-18 16:02:39 +053099 * @param ospfProcesses updated process instances
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530100 */
Ray Milkey019fba42018-01-31 14:07:47 -0800101 public void updateInterfaceMap(List<OspfProcess> ospfProcesses) {
sunishvkf7c56552016-07-18 16:02:39 +0530102 for (OspfProcess ospfUpdatedProcess : ospfProcesses) {
103 for (OspfArea updatedArea : ospfUpdatedProcess.areas()) {
104 for (OspfInterface ospfUpdatedInterface : updatedArea.ospfInterfaceList()) {
105 OspfInterface ospfInterface = ospfInterfaceMap.get(ospfUpdatedInterface.interfaceIndex());
106 if (ospfInterface == null) {
107 ospfUpdatedInterface.setOspfArea(updatedArea);
108 ((OspfInterfaceImpl) ospfUpdatedInterface).setController(controller);
109 ((OspfInterfaceImpl) ospfUpdatedInterface).setState(OspfInterfaceState.DOWN);
110 ospfUpdatedInterface.setDr(Ip4Address.valueOf("0.0.0.0"));
111 ospfUpdatedInterface.setBdr(Ip4Address.valueOf("0.0.0.0"));
112 ospfInterfaceMap.put(ospfUpdatedInterface.interfaceIndex(), ospfUpdatedInterface);
113 ((OspfInterfaceImpl) ospfUpdatedInterface).setChannel(channel);
114 ospfUpdatedInterface.interfaceUp();
115 ospfUpdatedInterface.startDelayedAckTimer();
116 } else {
117 ospfInterface.setOspfArea(updatedArea);
118
119 if (ospfInterface.routerDeadIntervalTime() != ospfUpdatedInterface.routerDeadIntervalTime()) {
120 ospfInterface.setRouterDeadIntervalTime(ospfUpdatedInterface.routerDeadIntervalTime());
121 Map<String, OspfNbr> neighbors = ospfInterface.listOfNeighbors();
122 for (String key : neighbors.keySet()) {
123 OspfNbr ospfNbr = ospfInterface.neighbouringRouter(key);
124 ospfNbr.setRouterDeadInterval(ospfInterface.routerDeadIntervalTime());
125 ospfNbr.stopInactivityTimeCheck();
126 ospfNbr.startInactivityTimeCheck();
127 }
128 }
129 if (ospfInterface.interfaceType() != ospfUpdatedInterface.interfaceType()) {
130 ospfInterface.setInterfaceType(ospfUpdatedInterface.interfaceType());
131 if (ospfInterface.interfaceType() == OspfInterfaceType.POINT_TO_POINT.value()) {
132 ospfInterface.setDr(Ip4Address.valueOf("0.0.0.0"));
133 ospfInterface.setBdr(Ip4Address.valueOf("0.0.0.0"));
134 }
135 ospfInterface.removeNeighbors();
136 }
137 if (ospfInterface.helloIntervalTime() != ospfUpdatedInterface.helloIntervalTime()) {
138 ospfInterface.setHelloIntervalTime(ospfUpdatedInterface.helloIntervalTime());
139 ospfInterface.stopHelloTimer();
140 ospfInterface.startHelloTimer();
141 }
142 ospfInterfaceMap.put(ospfInterface.interfaceIndex(), ospfInterface);
143 }
144 }
145 }
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530146 }
147 }
148
149 /**
sunishvkf7c56552016-07-18 16:02:39 +0530150 * Initialize channel, start hello sender and initialize LSDB.
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530151 */
Ray Milkey019fba42018-01-31 14:07:47 -0800152 private void initialize() {
sunishvkf7c56552016-07-18 16:02:39 +0530153 log.debug("OspfChannelHandler initialize..!!!");
154 if (configPacket != null) {
155 log.debug("OspfChannelHandler initialize -> sentConfig packet of length ::"
156 + configPacket.length);
157 sentConfigPacket(configPacket);
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530158 }
sunishvkf7c56552016-07-18 16:02:39 +0530159 initializeInterfaceMap();
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530160 }
161
162 @Override
Ray Milkey019fba42018-01-31 14:07:47 -0800163 public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent evt) {
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530164 log.info("OSPF channelConnected from {}", evt.getChannel().getRemoteAddress());
sunishvkf7c56552016-07-18 16:02:39 +0530165 this.channel = evt.getChannel();
166 initialize();
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530167 }
168
169 @Override
170 public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent evt) {
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530171 log.debug("OspfChannelHandler::channelDisconnected...!!!");
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530172
sunishvkf7c56552016-07-18 16:02:39 +0530173 for (Integer interfaceIndex : ospfInterfaceMap.keySet()) {
174 OspfInterface anInterface = ospfInterfaceMap.get(interfaceIndex);
175 if (anInterface != null) {
176 anInterface.interfaceDown();
177 anInterface.stopDelayedAckTimer();
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530178 }
sunishvkf7c56552016-07-18 16:02:39 +0530179 }
180
181 if (controller != null) {
182 controller.connectPeer();
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530183 }
184 }
185
186 @Override
Ray Milkey019fba42018-01-31 14:07:47 -0800187 public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
sunishvkf7c56552016-07-18 16:02:39 +0530188 log.debug("[exceptionCaught]: " + e.toString());
189 if (e.getCause() instanceof ReadTimeoutException) {
190 log.debug("Disconnecting device {} due to read timeout", e.getChannel().getRemoteAddress());
191 return;
192 } else if (e.getCause() instanceof ClosedChannelException) {
193 log.debug("Channel for OSPF {} already closed", e.getChannel().getRemoteAddress());
194 } else if (e.getCause() instanceof IOException) {
195 log.debug("Disconnecting OSPF {} due to IO Error: {}", e.getChannel().getRemoteAddress(),
196 e.getCause().getMessage());
197 } else if (e.getCause() instanceof OspfParseException) {
198 OspfParseException errMsg = (OspfParseException) e.getCause();
199 byte errorCode = errMsg.errorCode();
200 byte errorSubCode = errMsg.errorSubCode();
201 log.debug("Error while parsing message from OSPF {}, ErrorCode {}",
202 e.getChannel().getRemoteAddress(), errorCode);
203 } else if (e.getCause() instanceof RejectedExecutionException) {
204 log.debug("Could not process message: queue full");
205 } else {
206 log.debug("Error while processing message from OSPF {}, {}",
207 e.getChannel().getRemoteAddress(), e.getCause().getMessage());
208 }
209 }
210
211 @Override
Ray Milkey019fba42018-01-31 14:07:47 -0800212 public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530213 log.debug("OspfChannelHandler::messageReceived...!!!");
214 Object message = e.getMessage();
215 if (message instanceof List) {
216 List<OspfMessage> ospfMessageList = (List<OspfMessage>) message;
sunishvkf7c56552016-07-18 16:02:39 +0530217 log.debug("OspfChannelHandler::List of IsisMessages Size {}", ospfMessageList.size());
Ray Milkeyfe0e0852018-01-18 11:14:05 -0800218
219 for (OspfMessage ospfMessage : ospfMessageList) {
220 processOspfMessage(ospfMessage, ctx);
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530221 }
222 }
223 if (message instanceof OspfMessage) {
224 OspfMessage ospfMessage = (OspfMessage) message;
225 log.debug("OspfChannelHandler::OspfMessages received...!!");
sunish vkaa48da82016-03-02 23:17:06 +0530226 processOspfMessage(ospfMessage, ctx);
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530227 }
228 }
229
230 /**
231 * When an OSPF message received it is handed over to this method.
232 * Based on the type of the OSPF message received it will be handed over
233 * to corresponding message handler methods.
234 *
235 * @param ospfMessage received OSPF message
236 * @param ctx channel handler context instance.
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530237 */
Ray Milkey019fba42018-01-31 14:07:47 -0800238 private void processOspfMessage(OspfMessage
239 ospfMessage, ChannelHandlerContext ctx) {
sunish vkaa48da82016-03-02 23:17:06 +0530240 log.debug("OspfChannelHandler::processOspfMessage...!!!");
sunishvkf7c56552016-07-18 16:02:39 +0530241 int interfaceIndex = ospfMessage.interfaceIndex();
242 OspfInterface ospfInterface = ospfInterfaceMap.get(interfaceIndex);
243 if (ospfInterface != null) {
244 ospfInterface.processOspfMessage(ospfMessage, ctx);
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530245 }
246 }
247
248 /**
sunishvkf7c56552016-07-18 16:02:39 +0530249 * Sends the interface configuration packet to server.
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530250 *
sunishvkf7c56552016-07-18 16:02:39 +0530251 * @param configPacket interface configuration
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530252 */
sunishvkf7c56552016-07-18 16:02:39 +0530253 public void sentConfigPacket(byte[] configPacket) {
254 if (channel != null) {
255 channel.write(configPacket);
256 log.debug("OspfChannelHandler sentConfigPacket packet sent..!!!");
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530257 } else {
sunishvkf7c56552016-07-18 16:02:39 +0530258 log.debug("OspfChannelHandler sentConfigPacket channel not connected - re try..!!!");
259 this.configPacket = configPacket;
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530260 }
261 }
262}