blob: 29af59632ee9cd50c0fddcbf21515b2cf309e716 [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 com.google.common.collect.ImmutableList;
19import com.google.common.collect.Lists;
Jian Li6322a362016-10-31 00:57:19 +090020import io.netty.bootstrap.Bootstrap;
21import io.netty.buffer.PooledByteBufAllocator;
Jian Li5ba6ec12016-11-18 02:38:58 +090022import io.netty.channel.AbstractChannel;
Jian Li451cea32016-10-04 15:27:50 +090023import io.netty.channel.ChannelFuture;
24import io.netty.channel.ChannelOption;
25import io.netty.channel.EventLoopGroup;
Jian Li5ba6ec12016-11-18 02:38:58 +090026import io.netty.channel.epoll.EpollDatagramChannel;
27import io.netty.channel.epoll.EpollEventLoopGroup;
Jian Li451cea32016-10-04 15:27:50 +090028import io.netty.channel.nio.NioEventLoopGroup;
Jian Li6322a362016-10-31 00:57:19 +090029import io.netty.channel.socket.nio.NioDatagramChannel;
Jian Li451cea32016-10-04 15:27:50 +090030import org.slf4j.Logger;
31import org.slf4j.LoggerFactory;
32
33import java.net.InetSocketAddress;
34import java.util.List;
35
36/**
Jian Li451cea32016-10-04 15:27:50 +090037 * Bootstraps LISP netty channel, handles all setup and network listeners.
38 */
Jian Li6322a362016-10-31 00:57:19 +090039public class LispControllerBootstrap {
Jian Li451cea32016-10-04 15:27:50 +090040
Jian Li6322a362016-10-31 00:57:19 +090041 protected static final Logger log = LoggerFactory.getLogger(LispControllerBootstrap.class);
Jian Li451cea32016-10-04 15:27:50 +090042
43 private static final int LISP_DATA_PORT = 4341;
44 private static final int LISP_CONTROL_PORT = 4342;
45
46 // Configuration options
47 protected List<Integer> lispPorts = ImmutableList.of(LISP_DATA_PORT, LISP_CONTROL_PORT);
48
Jian Li6322a362016-10-31 00:57:19 +090049 private EventLoopGroup eventLoopGroup;
Jian Li5ba6ec12016-11-18 02:38:58 +090050 private Class<? extends AbstractChannel> channelClass;
Jian Li451cea32016-10-04 15:27:50 +090051
52 /**
53 * Stitches all channel handlers into server bootstrap.
54 */
Jian Li5ba6ec12016-11-18 02:38:58 +090055 private void run() {
Jian Li451cea32016-10-04 15:27:50 +090056
57 try {
Jian Li6322a362016-10-31 00:57:19 +090058 final Bootstrap bootstrap = createServerBootstrap();
Jian Li451cea32016-10-04 15:27:50 +090059
60 configBootstrapOptions(bootstrap);
61
62 List<ChannelFuture> channelFutures = Lists.newArrayList();
63
64 lispPorts.forEach(p -> {
65 InetSocketAddress sa = new InetSocketAddress(p);
66 channelFutures.add(bootstrap.bind(sa));
67 log.info("Listening for LISP router connections on {}", sa);
68 });
69
70 for (ChannelFuture f : channelFutures) {
71 f.sync();
72 }
73
74 } catch (Exception e) {
75 throw new RuntimeException(e);
76 }
77 }
78
79 /**
80 * Initializes server bootstrap with given LISP channel initializer.
81 *
82 * @return initialized server bootstrap
83 */
Jian Li6322a362016-10-31 00:57:19 +090084 private Bootstrap createServerBootstrap() {
85 Bootstrap bootstrap = new Bootstrap();
Jian Li5ba6ec12016-11-18 02:38:58 +090086
87 initEventLoopGroup();
Jian Li6322a362016-10-31 00:57:19 +090088 bootstrap.group(eventLoopGroup)
Jian Li5ba6ec12016-11-18 02:38:58 +090089 .channel(channelClass)
Jian Li6322a362016-10-31 00:57:19 +090090 .handler(new LispChannelInitializer());
Jian Li451cea32016-10-04 15:27:50 +090091
92 return bootstrap;
93 }
94
95 /**
96 * Configures bootstrap options to tune the communication performance.
97 *
98 * @param bootstrap LISP server bootstrap
99 */
Jian Li6322a362016-10-31 00:57:19 +0900100 private void configBootstrapOptions(Bootstrap bootstrap) {
101 bootstrap.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
Jian Li451cea32016-10-04 15:27:50 +0900102 }
103
104 /**
105 * Closes all open channels.
106 *
107 * @param channelFutures a collection of channel futures
108 */
109 private void closeChannels(List<ChannelFuture> channelFutures) {
110 try {
111 for (ChannelFuture f : channelFutures) {
112 f.channel().closeFuture().sync();
113 }
114 } catch (InterruptedException e) {
Jian Li5ba6ec12016-11-18 02:38:58 +0900115 log.warn("Failed to close channels. Reasons: {}.", e.getMessage());
Jian Li451cea32016-10-04 15:27:50 +0900116 }
117 }
118
119 /**
Jian Li5ba6ec12016-11-18 02:38:58 +0900120 * Initializes event loop group.
121 */
122 private void initEventLoopGroup() {
123
124 // try to use EpollEventLoopGroup if possible,
125 // if OS does not support native Epoll, fallback to use netty NIO
126 try {
127 eventLoopGroup = new EpollEventLoopGroup();
128 channelClass = EpollDatagramChannel.class;
129 } catch (Throwable e) {
130 log.debug("Failed to initialize native (epoll) transport. "
131 + "Reason: {}. Proceeding with NIO event group.", e.getMessage());
132 }
133 eventLoopGroup = new NioEventLoopGroup();
134 channelClass = NioDatagramChannel.class;
135 }
136
137 /**
Jian Li451cea32016-10-04 15:27:50 +0900138 * Launches LISP controller to listen control channel.
139 */
140 public void start() {
141 log.info("Starting LISP control I/O");
142
143 this.run();
144 }
145
146 /**
147 * Terminates LISP controller and lease all occupied resources.
148 */
149 public void stop() {
150 log.info("Stopping LISP control I/O");
151
152 try {
153 // try to shutdown all open event groups
Jian Li6322a362016-10-31 00:57:19 +0900154 eventLoopGroup.shutdownGracefully().sync();
Jian Li451cea32016-10-04 15:27:50 +0900155 } catch (InterruptedException e) {
Jian Li5ba6ec12016-11-18 02:38:58 +0900156 log.warn("Failed to stop LISP controller. Reasons: {}.", e.getMessage());
Jian Li451cea32016-10-04 15:27:50 +0900157 }
158 }
159}