blob: 500c0919b6d79870b2649444e9e58671439e8d3e [file] [log] [blame]
DongRyeol Cha5f870032018-07-12 18:36:20 +09001/*
2 * Copyright 2018-present Open Networking Foundation
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 */
16
17package org.onosproject.drivers.juniper;
18
19import static com.google.common.base.Preconditions.checkNotNull;
20import static org.onosproject.drivers.juniper.JuniperUtils.cliDeleteRequestBuilder;
21import static org.onosproject.drivers.juniper.JuniperUtils.cliSetRequestBuilder;
22import static org.onosproject.drivers.juniper.JuniperUtils.getOpenFlowControllersFromConfig;
23import static org.slf4j.LoggerFactory.getLogger;
24
25import com.google.common.collect.Lists;
26import org.onosproject.drivers.utilities.XmlConfigParser;
27
28import java.util.List;
29
30import org.onosproject.net.DeviceId;
31import org.onosproject.net.behaviour.ControllerConfig;
32import org.onosproject.net.behaviour.ControllerInfo;
33import org.onosproject.net.driver.AbstractHandlerBehaviour;
34import org.onosproject.netconf.NetconfController;
35import org.onosproject.netconf.NetconfDevice;
36import org.onosproject.netconf.NetconfException;
37import org.onosproject.netconf.NetconfSession;
38import org.slf4j.Logger;
39
40import java.io.ByteArrayInputStream;
41
42/**
43 * Set and get the openflow controller information via NETCONF for Juniper Switch. *
44 */
45public class ControllerConfigJuniperImpl extends AbstractHandlerBehaviour implements ControllerConfig {
46
47 private final Logger log = getLogger(getClass());
48
49 private static final String RPC_TAG_NETCONF_BASE = "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">";
50 private static final String RPC_CLOSE_TAG = "</rpc>";
51
52 @Override
53 public List<ControllerInfo> getControllers() {
54 List<ControllerInfo> controllers = Lists.newArrayList();
55 String reply = retrieveResultCommand(buildRpcGetOpenFlowController());
56
57 if (reply == null || (reply != null && reply.isEmpty())) {
58 log.error("Cannot get the controllers from switch");
59 } else {
60 controllers = getOpenFlowControllersFromConfig(XmlConfigParser
61 .loadXml(new ByteArrayInputStream(reply.getBytes())));
62 log.debug("controllers {}", controllers);
63 }
64
65 return controllers;
66 }
67
68 @Override
69 public void setControllers(List<ControllerInfo> controllers) {
70 if (!requestCommand(buildRpcSetOpenFlowController(controllers))) {
71 log.error("Cannot set the controllers to switch");
72 }
73 }
74
75 @Override
76 public void removeControllers(List<ControllerInfo> controllers) {
77 if (!requestCommand(buildRpcRemoveOpenFlowController())) {
78 log.error("Cannot remove the controllers from switch");
79 }
80 }
81
82 private String buildRpcGetOpenFlowController() {
83 StringBuilder rpc = new StringBuilder(RPC_TAG_NETCONF_BASE);
84
85 rpc.append("<get-configuration>");
86 rpc.append("<configuration>");
87 rpc.append("<protocols>");
88 rpc.append("<openflow>");
89 rpc.append("<mode>");
90 rpc.append("<ofagent-mode>");
91 rpc.append("<controller>");
92 rpc.append("</controller>");
93 rpc.append("</ofagent-mode>");
94 rpc.append("</mode>");
95 rpc.append("</openflow>");
96 rpc.append("</protocols>");
97 rpc.append("</configuration>");
98 rpc.append("</get-configuration>");
99 rpc.append(RPC_CLOSE_TAG);
100 rpc.append("]]>]]>");
101
102 return rpc.toString();
103 }
104
105 private String buildRpcSetOpenFlowController(List<ControllerInfo> controllers) {
106 StringBuilder request = new StringBuilder();
107
108 request.append("<protocols>");
109 request.append("<openflow operation=\"delete\"/>");
110 request.append("</protocols>");
111
112 request.append("<protocols>");
113 request.append("<openflow>");
114 request.append("<mode>");
115 request.append("<ofagent-mode>");
116
117 request.append("<controller>");
118 for (int i = 0; i < controllers.size(); i++) {
119 request.append("<ip>");
120 request.append("<name>");
121 request.append(controllers.get(i).ip().toString());
122 request.append("</name>");
123 request.append("<protocol>");
124 request.append("<tcp>");
125 request.append("<port>");
126 request.append(Integer.toString(controllers.get(i).port()));
127 request.append("</port>");
128 request.append("</tcp>");
129 request.append("</protocol>");
130 request.append("</ip>");
131 }
132 request.append("</controller>");
133 request.append("</ofagent-mode>");
134 request.append("</mode>");
135 request.append("</openflow>");
136 request.append("</protocols>");
137
138 return cliSetRequestBuilder(request);
139 }
140
141 private String buildRpcRemoveOpenFlowController() {
142 StringBuilder request = new StringBuilder();
143
144 request.append("<protocols>");
145 request.append("<openflow>");
146 request.append("<mode>");
147 request.append("<ofagent-mode>");
148 request.append("<controller operation=\"delete\"/>");
149 request.append("</ofagent-mode>");
150 request.append("</mode>");
151 request.append("</openflow>");
152 request.append("</protocols>");
153
154 return cliDeleteRequestBuilder(request);
155 }
156
157 private String buildCommit() {
158 StringBuilder rpc = new StringBuilder(RPC_TAG_NETCONF_BASE);
159
160 rpc.append("<commit/>");
161 rpc.append(RPC_CLOSE_TAG);
162 rpc.append("]]>]]>");
163
164 return rpc.toString();
165 }
166
167 private String buildDiscardChanges() {
168 StringBuilder rpc = new StringBuilder(RPC_TAG_NETCONF_BASE);
169
170 rpc.append("<discard-changes/>");
171 rpc.append(RPC_CLOSE_TAG);
172 rpc.append("]]>]]>");
173
174 return rpc.toString();
175 }
176
177 private NetconfSession getSession() {
178 NetconfController controller = checkNotNull(handler().get(NetconfController.class));
179 DeviceId deviceId = handler().data().deviceId();
180 NetconfDevice device = controller.getDevicesMap().get(deviceId);
181
182 if (device == null) {
183 log.error("Cannot find the netconf device : {}", deviceId);
184 return null;
185 }
186
187 return device.getSession();
188 }
189
190 private String retrieveResultCommand(String command) {
191 NetconfSession session = getSession();
192 String reply;
193
194 if (session == null) {
195 log.error("Cannot get session : {}", command);
196 return null;
197 }
198
199 try {
200 reply = session.requestSync(command).trim();
201 log.debug(reply);
202 } catch (NetconfException e) {
203 log.debug(e.getMessage());
204 return null;
205 }
206
207 return reply;
208 }
209
210 private boolean requestCommand(String command) {
211 NetconfSession session = getSession();
212
213 if (session == null) {
214 log.error("Cannot get session : {}", command);
215 return false;
216 }
217
218 try {
219 String reply = session.requestSync(command).trim();
220 log.debug(reply);
221
222 if (!isOK(reply)) {
223 log.error("discard changes {}", reply);
224 session.requestSync(buildDiscardChanges());
225 return false;
226 }
227
228 reply = session.requestSync(buildCommit()).trim();
229 log.debug(reply);
230 } catch (NetconfException e) {
231 log.debug(e.getMessage());
232 return false;
233 }
234
235 return true;
236 }
237
238 private boolean isOK(String reply) {
239 if (reply != null && reply.indexOf("<ok/>") >= 0) {
240 return true;
241 }
242 return false;
243 }
244}