blob: c12c520878e9d5c80df4502ab9df6578dc9380fa [file] [log] [blame]
tejeshwer degala3fe1ed52016-04-22 17:04:01 +05301/*
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 */
16package org.onosproject.isis.controller.impl;
17
18import com.fasterxml.jackson.databind.JsonNode;
19import org.jboss.netty.bootstrap.ClientBootstrap;
20import org.jboss.netty.channel.AdaptiveReceiveBufferSizePredictor;
21import org.jboss.netty.channel.ChannelFuture;
22import org.jboss.netty.channel.ChannelPipelineFactory;
23import org.jboss.netty.channel.FixedReceiveBufferSizePredictorFactory;
24import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
25import org.onlab.packet.Ip4Address;
26import org.onlab.packet.MacAddress;
27import org.onlab.packet.TpPort;
28import org.onosproject.isis.controller.IsisInterface;
29import org.onosproject.isis.controller.IsisNetworkType;
30import org.onosproject.isis.controller.IsisProcess;
31import org.onosproject.isis.controller.IsisRouterType;
32import org.onosproject.isis.io.util.IsisConstants;
33import org.slf4j.Logger;
34import org.slf4j.LoggerFactory;
35
36import java.net.InetAddress;
37import java.net.InetSocketAddress;
38import java.net.UnknownHostException;
39import java.util.ArrayList;
40import java.util.List;
41import java.util.concurrent.Executors;
42
43import static org.onlab.util.Tools.groupedThreads;
44
45/**
46 * Representation of an ISIS controller.
47 */
48public class Controller {
49 protected static final int BUFFER_SIZE = 4 * 1024 * 1024;
50 private static final Logger log = LoggerFactory.getLogger(Controller.class);
51 private final int peerWorkerThreads = 16;
52 private List<IsisProcess> processes = null;
53 private IsisChannelHandler isisChannelHandler;
54 private NioClientSocketChannelFactory peerExecFactory;
55 private ClientBootstrap peerBootstrap = null;
56 private TpPort isisPort = TpPort.tpPort(IsisConstants.SPORT);
57
58 /**
59 * Deactivates ISIS controller.
60 */
61 public void isisDeactivate() {
62 peerExecFactory.shutdown();
63 }
64
65 /**
66 * Updates the processes configuration.
67 *
68 * @param jsonNode json node instance
69 * @throws Exception might throws parse exception
70 */
71 public void updateConfig(JsonNode jsonNode) throws Exception {
72 log.debug("Controller::UpdateConfig called");
73 byte[] configPacket = new byte[IsisConstants.CONFIG_LENGTH];
74 byte numberOfInterface = 0; // number of interfaces to configure
75
76 configPacket[0] = (byte) 0xFF; // its a conf packet - identifier
77 List<IsisProcess> isisProcesses = getConfig(jsonNode);
78
79 for (IsisProcess isisProcess : isisProcesses) {
80 log.debug("IsisProcessDetails : " + isisProcess);
81 for (IsisInterface isisInterface : isisProcess.isisInterfaceList()) {
82 DefaultIsisInterface isisInterfaceImpl = (DefaultIsisInterface) isisInterface;
83 log.debug("IsisInterfaceDetails : " + isisInterface);
84 numberOfInterface++;
85 configPacket[2 * numberOfInterface] = (byte) isisInterfaceImpl.interfaceIndex();
86 if (isisInterface.networkType() == IsisNetworkType.BROADCAST &&
87 isisInterfaceImpl.reservedPacketCircuitType() == IsisRouterType.L1.value()) {
88 configPacket[(2 * numberOfInterface) + 1] = (byte) 0;
89 } else if (isisInterface.networkType() == IsisNetworkType.BROADCAST &&
90 isisInterfaceImpl.reservedPacketCircuitType() == IsisRouterType.L2.value()) {
91 configPacket[(2 * numberOfInterface) + 1] = (byte) 1;
92 } else if (isisInterface.networkType() == IsisNetworkType.P2P) {
93 configPacket[(2 * numberOfInterface) + 1] = (byte) 2;
94 } else if (isisInterface.networkType() == IsisNetworkType.BROADCAST &&
95 isisInterfaceImpl.reservedPacketCircuitType() == IsisRouterType.L1L2.value()) {
96 configPacket[(2 * numberOfInterface) + 1] = (byte) 3;
97 }
98 }
99 }
100 configPacket[1] = numberOfInterface;
101 //First time configuration
102 if (processes == null) {
103 processes = isisProcesses;
104 //Initialize connection by creating a channel handler instance and sent the config packet);
105 initConnection();
106 //Initializing the interface map in channel handler
107 isisChannelHandler.initializeInterfaceMap();
108 } else {
109 isisChannelHandler.updateInterfaceMap(isisProcesses);
110 }
111 //Send the config packet
112 isisChannelHandler.sentConfigPacket(configPacket);
113 }
114
115 /**
116 * Initializes the netty client channel connection.
117 */
118 private void initConnection() {
119 if (peerBootstrap != null) {
120 return;
121 }
122 peerBootstrap = createPeerBootStrap();
123
124 peerBootstrap.setOption("reuseAddress", true);
125 peerBootstrap.setOption("tcpNoDelay", true);
126 peerBootstrap.setOption("keepAlive", true);
127 peerBootstrap.setOption("receiveBufferSize", Controller.BUFFER_SIZE);
128 peerBootstrap.setOption("receiveBufferSizePredictorFactory",
129 new FixedReceiveBufferSizePredictorFactory(
130 Controller.BUFFER_SIZE));
131 peerBootstrap.setOption("receiveBufferSizePredictor",
132 new AdaptiveReceiveBufferSizePredictor(64, 1024, 65536));
133 peerBootstrap.setOption("child.keepAlive", true);
134 peerBootstrap.setOption("child.tcpNoDelay", true);
135 peerBootstrap.setOption("child.sendBufferSize", Controller.BUFFER_SIZE);
136 peerBootstrap.setOption("child.receiveBufferSize", Controller.BUFFER_SIZE);
137 peerBootstrap.setOption("child.receiveBufferSizePredictorFactory",
138 new FixedReceiveBufferSizePredictorFactory(
139 Controller.BUFFER_SIZE));
140 peerBootstrap.setOption("child.reuseAddress", true);
141
142 isisChannelHandler = new IsisChannelHandler(this, processes);
143 ChannelPipelineFactory pfact = new IsisPipelineFactory(isisChannelHandler);
144 peerBootstrap.setPipelineFactory(pfact);
145 ChannelFuture connection = peerBootstrap.connect(new InetSocketAddress(IsisConstants.SHOST, isisPort.toInt()));
146 }
147
148 /**
149 * Creates peer boot strap.
150 *
151 * @return client bootstrap instance
152 */
153 private ClientBootstrap createPeerBootStrap() {
154
155 if (peerWorkerThreads == 0) {
156 peerExecFactory = new NioClientSocketChannelFactory(
157 Executors.newCachedThreadPool(groupedThreads("onos/isis", "boss-%d")),
158 Executors.newCachedThreadPool(groupedThreads("onos/isis", "worker-%d")));
159 return new ClientBootstrap(peerExecFactory);
160 } else {
161 peerExecFactory = new NioClientSocketChannelFactory(
162 Executors.newCachedThreadPool(groupedThreads("onos/isis", "boss-%d")),
163 Executors.newCachedThreadPool(groupedThreads("onos/isis", "worker-%d")),
164 peerWorkerThreads);
165 return new ClientBootstrap(peerExecFactory);
166 }
167 }
168
169 /**
170 * Gets all configured processes.
171 *
172 * @return all configured processes
173 */
174 public List<IsisProcess> getAllConfiguredProcesses() {
175 return processes;
176 }
177
178 /**
179 * Gets the list of processes configured.
180 *
181 * @param json posted json
182 * @return list of processes configured
183 */
184 private List<IsisProcess> getConfig(JsonNode json) throws Exception {
185
186 List<IsisProcess> isisProcessesList = new ArrayList<>();
187 JsonNode jsonNodes = json;
188
189 if (jsonNodes == null) {
190 return isisProcessesList;
191 }
192 jsonNodes.forEach(jsonNode -> {
193 List<IsisInterface> interfaceList = new ArrayList<>();
194 for (JsonNode jsonNode1 : jsonNode.path(IsisConstants.INTERFACE)) {
195 IsisInterface isisInterface = new DefaultIsisInterface();
196 isisInterface.setInterfaceIndex(jsonNode1.path(IsisConstants.INTERFACEINDEX).asInt());
197 isisInterface.setInterfaceIpAddress(Ip4Address.valueOf(jsonNode1
198 .path(IsisConstants.INTERFACEIP)
199 .asText()));
200 try {
201 isisInterface.setNetworkMask(InetAddress.getByName((jsonNode1
202 .path(IsisConstants.NETWORKMASK).asText())).getAddress());
203 } catch (UnknownHostException e) {
204 log.debug("Error:: Parsing network mask");
205 }
206 isisInterface.setInterfaceMacAddress(MacAddress.valueOf(jsonNode1
207 .path(IsisConstants.MACADDRESS)
208 .asText()));
209 isisInterface.setIntermediateSystemName(jsonNode1
210 .path(IsisConstants.INTERMEDIATESYSTEMNAME)
211 .asText());
212 isisInterface.setSystemId(jsonNode1.path(IsisConstants.SYSTEMID).asText());
213 isisInterface.setReservedPacketCircuitType(jsonNode1
214 .path(IsisConstants.RESERVEDPACKETCIRCUITTYPE)
215 .asInt());
216 if (isisInterface.reservedPacketCircuitType() == IsisRouterType.L1.value()) {
217 isisInterface.setL1LanId(jsonNode1.path(IsisConstants.LANID).asText());
218 }
219 isisInterface.setIdLength(jsonNode1.path(IsisConstants.IDLENGTH).asInt());
220 isisInterface.setMaxAreaAddresses(jsonNode1.path(IsisConstants.MAXAREAADDRESSES).asInt());
221 isisInterface.setNetworkType(IsisNetworkType.get(jsonNode1
222 .path(IsisConstants.NETWORKTYPE)
223 .asInt()));
224 isisInterface.setAreaAddress(jsonNode1.path(IsisConstants.AREAADDRESS).asText());
225 isisInterface.setAreaLength(jsonNode1.path(IsisConstants.AREALENGTH).asInt());
226 isisInterface.setLspId(jsonNode1.path(IsisConstants.LSPID).asText());
227 isisInterface.setCircuitId(jsonNode1.path(IsisConstants.CIRCUITID).asText());
228 isisInterface.setHoldingTime(jsonNode1.path(IsisConstants.HOLDINGTIME).asInt());
229 isisInterface.setPriority(jsonNode1.path(IsisConstants.PRIORITY).asInt());
230 isisInterface.setHelloInterval(jsonNode1.path(IsisConstants.HELLOINTERVAL).asInt());
231 interfaceList.add(isisInterface);
232 }
233 IsisProcess process = new DefaultIsisProcess();
234 process.setProcessId(jsonNode.path(IsisConstants.PROCESSESID).asText());
235 process.setIsisInterfaceList(interfaceList);
236 isisProcessesList.add(process);
237 });
238
239 return isisProcessesList;
240 }
241}