blob: 1e3be19ab80efb6e25346dd95632e8486ae6188d [file] [log] [blame]
Jian Li451cea32016-10-04 15:27:50 +09001/*
2 * Copyright 2016-present Open Networking Laboratory
3 *
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 */
Jian Li5e505c62016-12-05 02:44:24 +090016package org.onosproject.lisp.ctl.impl;
Jian Li451cea32016-10-04 15:27:50 +090017
18import io.netty.channel.ChannelHandlerContext;
19import io.netty.channel.ChannelInboundHandlerAdapter;
20import io.netty.handler.timeout.IdleState;
21import io.netty.handler.timeout.IdleStateEvent;
Jian Liafe2d3f2016-11-01 02:49:07 +090022import io.netty.util.ReferenceCountUtil;
Jian Lib1a8fd02016-12-27 03:55:32 +090023import org.onlab.packet.IpAddress;
24import org.onosproject.lisp.ctl.LispRouter;
25import org.onosproject.lisp.ctl.LispRouterFactory;
Jian Lif11594a2016-10-31 18:16:02 +090026import org.onosproject.lisp.msg.protocols.LispEncapsulatedControl;
Jian Li5e505c62016-12-05 02:44:24 +090027import org.onosproject.lisp.msg.protocols.LispInfoReply;
28import org.onosproject.lisp.msg.protocols.LispInfoRequest;
Jian Lib1a8fd02016-12-27 03:55:32 +090029import org.onosproject.lisp.msg.protocols.LispMapNotify;
30import org.onosproject.lisp.msg.protocols.LispMapRegister;
Jian Li451cea32016-10-04 15:27:50 +090031import org.onosproject.lisp.msg.protocols.LispMapRequest;
Jian Lif11594a2016-10-31 18:16:02 +090032import org.onosproject.lisp.msg.protocols.LispMessage;
Jian Li451cea32016-10-04 15:27:50 +090033import org.slf4j.Logger;
34import org.slf4j.LoggerFactory;
35
Jian Licdbc0872016-12-05 17:23:53 +090036import java.util.List;
Jian Lif987cb12017-04-28 00:41:46 +090037import java.util.concurrent.ExecutorService;
38import java.util.concurrent.Executors;
Jian Licdbc0872016-12-05 17:23:53 +090039
Jian Lib1a8fd02016-12-27 03:55:32 +090040import static org.onlab.packet.IpAddress.valueOf;
Jian Lif987cb12017-04-28 00:41:46 +090041import static org.onlab.util.Tools.groupedThreads;
Jian Lib1a8fd02016-12-27 03:55:32 +090042
Jian Li451cea32016-10-04 15:27:50 +090043/**
44 * Channel handler deals with the xTR connection and dispatches xTR messages
45 * to the appropriate locations.
46 */
47public class LispChannelHandler extends ChannelInboundHandlerAdapter {
48
49 private final Logger log = LoggerFactory.getLogger(getClass());
50
Jian Lib1a8fd02016-12-27 03:55:32 +090051 private final LispRouterFactory routerFactory = LispRouterFactory.getInstance();
52
Jian Lif987cb12017-04-28 00:41:46 +090053 protected ExecutorService executorMessages =
54 Executors.newFixedThreadPool(32, groupedThreads("onos/lisp", "message-stats-%d", log));
Jian Lib1a8fd02016-12-27 03:55:32 +090055
Jian Li451cea32016-10-04 15:27:50 +090056 @Override
57 public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
58
Jian Lif987cb12017-04-28 00:41:46 +090059 executorMessages.execute(new LispMessageHandler(ctx, (LispMessage) msg));
Jian Li451cea32016-10-04 15:27:50 +090060 }
61
62 @Override
63 public void userEventTriggered(ChannelHandlerContext ctx, Object evt)
64 throws Exception {
65
66 if (evt instanceof IdleStateEvent) {
67 IdleStateEvent event = (IdleStateEvent) evt;
68 if (event.state() == IdleState.READER_IDLE) {
69 log.info("READER_IDLE read timeout");
70 ctx.disconnect();
71 } else if (event.state() == IdleState.WRITER_IDLE) {
72 log.info("WRITER_IDLE write timeout");
73 ctx.disconnect();
74 } else if (event.state() == IdleState.ALL_IDLE) {
75 log.info("ALL_IDLE total timeout");
76 ctx.disconnect();
77 }
78 }
79 }
80
81 @Override
82 public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
83 throws Exception {
84 log.warn(cause.getMessage());
yoonseondb268672016-11-11 14:05:49 -080085
86 //TODO: add error handle mechanisms for each cases
Jian Li451cea32016-10-04 15:27:50 +090087 }
Jian Lif11594a2016-10-31 18:16:02 +090088
89 /**
90 * Extracts LISP message from encapsulated control message.
91 *
92 * @param ecm Encapsulated Control Message
93 * @return extracted LISP message
94 */
Jian Li1118c122016-11-01 21:58:15 +090095 private LispMessage extractLispMessage(LispEncapsulatedControl ecm) {
96 LispMessage message = ecm.getControlMessage();
97 message.configSender(ecm.getSender());
98 return message;
Jian Lif11594a2016-10-31 18:16:02 +090099 }
Jian Lif987cb12017-04-28 00:41:46 +0900100
101 /**
102 * LISP message handler.
103 */
104 private final class LispMessageHandler implements Runnable {
105
106 protected final ChannelHandlerContext ctx;
107 protected final LispMessage msg;
108 private LispRouter router;
109
110 public LispMessageHandler(ChannelHandlerContext ctx, LispMessage msg) {
111 this.ctx = ctx;
112 this.msg = msg;
113 }
114
115 @Override
116 public void run() {
117
118 try {
119 // process map-request message that is encapsulated in ECM
120 if (msg instanceof LispEncapsulatedControl) {
121 LispMessage innerMsg = extractLispMessage((LispEncapsulatedControl) msg);
122 if (innerMsg instanceof LispMapRequest) {
Jian Lib86d8ad2017-05-03 02:53:44 +0900123
124 IpAddress xtrAddress = valueOf(innerMsg.getSender().getAddress());
125
126 router = routerFactory.getRouterInstance(xtrAddress);
127
128 if (!router.isConnected()) {
129 router.setChannel(ctx.channel());
130 router.connectRouter();
131 }
132
133 router.setEidRecords(((LispMapRequest) innerMsg).getEids());
134 router.setSubscribed(true);
135 router.handleMessage(innerMsg);
136
Jian Lif987cb12017-04-28 00:41:46 +0900137 LispMapResolver mapResolver = LispMapResolver.getInstance();
138 List<LispMessage> lispMessages =
139 mapResolver.processMapRequest(msg);
140
141 if (lispMessages != null) {
142 lispMessages.forEach(ctx::writeAndFlush);
143 }
144 }
145 }
146
147 // process map-register message
148 if (msg instanceof LispMapRegister) {
149
150 LispMapRegister register = (LispMapRegister) msg;
151 IpAddress xtrAddress = valueOf(register.getSender().getAddress());
152 router = routerFactory.getRouterInstance(xtrAddress);
Jian Lib86d8ad2017-05-03 02:53:44 +0900153
154 if (!router.isConnected()) {
155 router.setChannel(ctx.channel());
156 router.connectRouter();
157 }
158
Jian Lif987cb12017-04-28 00:41:46 +0900159 router.handleMessage(register);
160
161 LispMapServer mapServer = LispMapServer.getInstance();
162 LispMapNotify mapNotify = mapServer.processMapRegister(register);
163
164 if (mapNotify != null) {
165 ctx.writeAndFlush(mapNotify);
166 }
167 }
168
169 // process info-request message
170 if (msg instanceof LispInfoRequest) {
171 LispMapServer mapServer = LispMapServer.getInstance();
172 LispInfoReply infoReply = mapServer.processInfoRequest(msg);
173
174 if (infoReply != null) {
175 ctx.writeAndFlush(infoReply);
176 }
177 }
178 } finally {
179 // try to remove the received message form the buffer
180 ReferenceCountUtil.release(msg);
181 }
182 }
183 }
Jian Li451cea32016-10-04 15:27:50 +0900184}