blob: 09a428fa7a6ca69b40f4a73e3c7f15b7c1bacf45 [file] [log] [blame]
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +05301/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2016-present Open Networking Laboratory
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 *
73 * @throws Exception might throws exception
74 */
sunishvkf7c56552016-07-18 16:02:39 +053075 public void initializeInterfaceMap() throws Exception {
76 for (OspfProcess process : processes) {
77 for (OspfArea area : process.areas()) {
78 for (OspfInterface ospfInterface : area.ospfInterfaceList()) {
79 OspfInterface anInterface = ospfInterfaceMap.get(ospfInterface.interfaceIndex());
80 if (anInterface == null) {
81 ospfInterface.setOspfArea(area);
82 ((OspfInterfaceImpl) ospfInterface).setController(controller);
83 ((OspfInterfaceImpl) ospfInterface).setState(OspfInterfaceState.DOWN);
84 ospfInterface.setDr(Ip4Address.valueOf("0.0.0.0"));
85 ospfInterface.setBdr(Ip4Address.valueOf("0.0.0.0"));
86 ospfInterfaceMap.put(ospfInterface.interfaceIndex(), ospfInterface);
87 }
88 ((OspfInterfaceImpl) ospfInterface).setChannel(channel);
89 ospfInterface.interfaceUp();
90 ospfInterface.startDelayedAckTimer();
91 }
92 //Initialize the LSDB and aging process
93 area.initializeDb();
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +053094 }
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +053095 }
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +053096 }
97
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +053098 /**
sunishvkf7c56552016-07-18 16:02:39 +053099 * Updates the interface map with interface details.
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530100 *
sunishvkf7c56552016-07-18 16:02:39 +0530101 * @param ospfProcesses updated process instances
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530102 * @throws Exception might throws exception
103 */
sunishvkf7c56552016-07-18 16:02:39 +0530104 public void updateInterfaceMap(List<OspfProcess> ospfProcesses) throws Exception {
105 for (OspfProcess ospfUpdatedProcess : ospfProcesses) {
106 for (OspfArea updatedArea : ospfUpdatedProcess.areas()) {
107 for (OspfInterface ospfUpdatedInterface : updatedArea.ospfInterfaceList()) {
108 OspfInterface ospfInterface = ospfInterfaceMap.get(ospfUpdatedInterface.interfaceIndex());
109 if (ospfInterface == null) {
110 ospfUpdatedInterface.setOspfArea(updatedArea);
111 ((OspfInterfaceImpl) ospfUpdatedInterface).setController(controller);
112 ((OspfInterfaceImpl) ospfUpdatedInterface).setState(OspfInterfaceState.DOWN);
113 ospfUpdatedInterface.setDr(Ip4Address.valueOf("0.0.0.0"));
114 ospfUpdatedInterface.setBdr(Ip4Address.valueOf("0.0.0.0"));
115 ospfInterfaceMap.put(ospfUpdatedInterface.interfaceIndex(), ospfUpdatedInterface);
116 ((OspfInterfaceImpl) ospfUpdatedInterface).setChannel(channel);
117 ospfUpdatedInterface.interfaceUp();
118 ospfUpdatedInterface.startDelayedAckTimer();
119 } else {
120 ospfInterface.setOspfArea(updatedArea);
121
122 if (ospfInterface.routerDeadIntervalTime() != ospfUpdatedInterface.routerDeadIntervalTime()) {
123 ospfInterface.setRouterDeadIntervalTime(ospfUpdatedInterface.routerDeadIntervalTime());
124 Map<String, OspfNbr> neighbors = ospfInterface.listOfNeighbors();
125 for (String key : neighbors.keySet()) {
126 OspfNbr ospfNbr = ospfInterface.neighbouringRouter(key);
127 ospfNbr.setRouterDeadInterval(ospfInterface.routerDeadIntervalTime());
128 ospfNbr.stopInactivityTimeCheck();
129 ospfNbr.startInactivityTimeCheck();
130 }
131 }
132 if (ospfInterface.interfaceType() != ospfUpdatedInterface.interfaceType()) {
133 ospfInterface.setInterfaceType(ospfUpdatedInterface.interfaceType());
134 if (ospfInterface.interfaceType() == OspfInterfaceType.POINT_TO_POINT.value()) {
135 ospfInterface.setDr(Ip4Address.valueOf("0.0.0.0"));
136 ospfInterface.setBdr(Ip4Address.valueOf("0.0.0.0"));
137 }
138 ospfInterface.removeNeighbors();
139 }
140 if (ospfInterface.helloIntervalTime() != ospfUpdatedInterface.helloIntervalTime()) {
141 ospfInterface.setHelloIntervalTime(ospfUpdatedInterface.helloIntervalTime());
142 ospfInterface.stopHelloTimer();
143 ospfInterface.startHelloTimer();
144 }
145 ospfInterfaceMap.put(ospfInterface.interfaceIndex(), ospfInterface);
146 }
147 }
148 }
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530149 }
150 }
151
152 /**
sunishvkf7c56552016-07-18 16:02:39 +0530153 * Initialize channel, start hello sender and initialize LSDB.
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530154 */
sunishvkf7c56552016-07-18 16:02:39 +0530155 private void initialize() throws Exception {
156 log.debug("OspfChannelHandler initialize..!!!");
157 if (configPacket != null) {
158 log.debug("OspfChannelHandler initialize -> sentConfig packet of length ::"
159 + configPacket.length);
160 sentConfigPacket(configPacket);
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530161 }
sunishvkf7c56552016-07-18 16:02:39 +0530162 initializeInterfaceMap();
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530163 }
164
165 @Override
166 public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent evt) throws Exception {
167 log.info("OSPF channelConnected from {}", evt.getChannel().getRemoteAddress());
sunishvkf7c56552016-07-18 16:02:39 +0530168 this.channel = evt.getChannel();
169 initialize();
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530170 }
171
172 @Override
173 public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent evt) {
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530174 log.debug("OspfChannelHandler::channelDisconnected...!!!");
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530175
sunishvkf7c56552016-07-18 16:02:39 +0530176 for (Integer interfaceIndex : ospfInterfaceMap.keySet()) {
177 OspfInterface anInterface = ospfInterfaceMap.get(interfaceIndex);
178 if (anInterface != null) {
179 anInterface.interfaceDown();
180 anInterface.stopDelayedAckTimer();
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530181 }
sunishvkf7c56552016-07-18 16:02:39 +0530182 }
183
184 if (controller != null) {
185 controller.connectPeer();
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530186 }
187 }
188
189 @Override
sunishvkf7c56552016-07-18 16:02:39 +0530190 public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent
191 e) throws Exception {
192 log.debug("[exceptionCaught]: " + e.toString());
193 if (e.getCause() instanceof ReadTimeoutException) {
194 log.debug("Disconnecting device {} due to read timeout", e.getChannel().getRemoteAddress());
195 return;
196 } else if (e.getCause() instanceof ClosedChannelException) {
197 log.debug("Channel for OSPF {} already closed", e.getChannel().getRemoteAddress());
198 } else if (e.getCause() instanceof IOException) {
199 log.debug("Disconnecting OSPF {} due to IO Error: {}", e.getChannel().getRemoteAddress(),
200 e.getCause().getMessage());
201 } else if (e.getCause() instanceof OspfParseException) {
202 OspfParseException errMsg = (OspfParseException) e.getCause();
203 byte errorCode = errMsg.errorCode();
204 byte errorSubCode = errMsg.errorSubCode();
205 log.debug("Error while parsing message from OSPF {}, ErrorCode {}",
206 e.getChannel().getRemoteAddress(), errorCode);
207 } else if (e.getCause() instanceof RejectedExecutionException) {
208 log.debug("Could not process message: queue full");
209 } else {
210 log.debug("Error while processing message from OSPF {}, {}",
211 e.getChannel().getRemoteAddress(), e.getCause().getMessage());
212 }
213 }
214
215 @Override
216 public void messageReceived(ChannelHandlerContext ctx, MessageEvent
217 e) throws Exception {
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530218 log.debug("OspfChannelHandler::messageReceived...!!!");
219 Object message = e.getMessage();
220 if (message instanceof List) {
221 List<OspfMessage> ospfMessageList = (List<OspfMessage>) message;
sunishvkf7c56552016-07-18 16:02:39 +0530222 log.debug("OspfChannelHandler::List of IsisMessages Size {}", ospfMessageList.size());
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530223 if (ospfMessageList != null) {
224 for (OspfMessage ospfMessage : ospfMessageList) {
sunish vkaa48da82016-03-02 23:17:06 +0530225 processOspfMessage(ospfMessage, ctx);
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530226 }
227 } else {
228 log.debug("OspfChannelHandler::OspfMessages Null List...!!");
229 }
230 }
231 if (message instanceof OspfMessage) {
232 OspfMessage ospfMessage = (OspfMessage) message;
233 log.debug("OspfChannelHandler::OspfMessages received...!!");
sunish vkaa48da82016-03-02 23:17:06 +0530234 processOspfMessage(ospfMessage, ctx);
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530235 }
236 }
237
238 /**
239 * When an OSPF message received it is handed over to this method.
240 * Based on the type of the OSPF message received it will be handed over
241 * to corresponding message handler methods.
242 *
243 * @param ospfMessage received OSPF message
244 * @param ctx channel handler context instance.
245 * @throws Exception might throws exception
246 */
sunishvkf7c56552016-07-18 16:02:39 +0530247 public void processOspfMessage(OspfMessage
248 ospfMessage, ChannelHandlerContext ctx) throws Exception {
sunish vkaa48da82016-03-02 23:17:06 +0530249 log.debug("OspfChannelHandler::processOspfMessage...!!!");
sunishvkf7c56552016-07-18 16:02:39 +0530250 int interfaceIndex = ospfMessage.interfaceIndex();
251 OspfInterface ospfInterface = ospfInterfaceMap.get(interfaceIndex);
252 if (ospfInterface != null) {
253 ospfInterface.processOspfMessage(ospfMessage, ctx);
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530254 }
255 }
256
257 /**
sunishvkf7c56552016-07-18 16:02:39 +0530258 * Sends the interface configuration packet to server.
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530259 *
sunishvkf7c56552016-07-18 16:02:39 +0530260 * @param configPacket interface configuration
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530261 */
sunishvkf7c56552016-07-18 16:02:39 +0530262 public void sentConfigPacket(byte[] configPacket) {
263 if (channel != null) {
264 channel.write(configPacket);
265 log.debug("OspfChannelHandler sentConfigPacket packet sent..!!!");
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530266 } else {
sunishvkf7c56552016-07-18 16:02:39 +0530267 log.debug("OspfChannelHandler sentConfigPacket channel not connected - re try..!!!");
268 this.configPacket = configPacket;
Kiran Ramachandrae8699cd2016-02-17 17:15:21 +0530269 }
270 }
271}