blob: ae703cfcced9e79b27f8139b38c986413470bc60 [file] [log] [blame]
Andreas Papazois92e4a042016-02-24 15:29:30 +02001/*
2 *
Brian O'Connor5ab426f2016-04-09 01:19:45 -07003 * * Copyright 2016-present Open Networking Laboratory
Andreas Papazois92e4a042016-02-24 15:29:30 +02004 * *
5 * * Licensed under the Apache License, Version 2.0 (the "License");
6 * * you may not use this file except in compliance with the License.
7 * * You may obtain a copy of the License at
8 * *
9 * * http://www.apache.org/licenses/LICENSE-2.0
10 * *
11 * * Unless required by applicable law or agreed to in writing, software
12 * * distributed under the License is distributed on an "AS IS" BASIS,
13 * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * * See the License for the specific language governing permissions and
15 * * limitations under the License.
16 *
17 */
18
19package org.onosproject.drivers.cisco;
20
21import org.onlab.packet.VlanId;
22import org.onosproject.drivers.utilities.XmlConfigParser;
23import org.onosproject.net.DeviceId;
24import org.onosproject.net.behaviour.InterfaceConfig;
Andreas Papazois1ed54cf2016-05-04 16:22:40 +030025import org.onosproject.net.device.DeviceInterfaceDescription;
Andreas Papazois92e4a042016-02-24 15:29:30 +020026import org.onosproject.net.driver.AbstractHandlerBehaviour;
27import org.onosproject.netconf.NetconfController;
28import org.onosproject.netconf.NetconfException;
29import org.onosproject.netconf.NetconfSession;
30import org.slf4j.Logger;
31
32import java.io.ByteArrayInputStream;
33import java.nio.charset.StandardCharsets;
Andreas Papazois59e19bb2016-04-12 13:59:58 +030034import java.util.List;
Andreas Papazois92e4a042016-02-24 15:29:30 +020035
36import static com.google.common.base.Preconditions.checkNotNull;
37import static org.slf4j.LoggerFactory.getLogger;
38
39/**
40 * Configures interfaces on Cisco IOS devices.
41 */
42public class InterfaceConfigCiscoIosImpl extends AbstractHandlerBehaviour
43 implements InterfaceConfig {
44
45 private final Logger log = getLogger(getClass());
46
47 /**
Andreas Papazois827d8d02016-04-15 11:53:16 +030048 * Adds an access interface to a VLAN.
Andreas Papazois1ed54cf2016-05-04 16:22:40 +030049 *
Andreas Papazois92e4a042016-02-24 15:29:30 +020050 * @param deviceId the device ID
51 * @param intf the name of the interface
52 * @param vlanId the VLAN ID
53 * @return the result of operation
54 */
55 @Override
Andreas Papazois827d8d02016-04-15 11:53:16 +030056 public boolean addAccessInterface(DeviceId deviceId, String intf, VlanId vlanId) {
Andreas Papazois92e4a042016-02-24 15:29:30 +020057 NetconfController controller = checkNotNull(handler()
58 .get(NetconfController.class));
59
60 NetconfSession session = controller.getDevicesMap().get(handler()
61 .data().deviceId()).getSession();
62 String reply;
63 try {
Andreas Papazois827d8d02016-04-15 11:53:16 +030064 reply = session.requestSync(addAccessInterfaceBuilder(intf, vlanId));
Andreas Papazois92e4a042016-02-24 15:29:30 +020065 } catch (NetconfException e) {
66 log.error("Failed to configure VLAN ID {} on device {} interface {}.",
67 vlanId, deviceId, intf, e);
68 return false;
69 }
70
71 return XmlConfigParser.configSuccess(XmlConfigParser.loadXml(
72 new ByteArrayInputStream(reply.getBytes(StandardCharsets.UTF_8))));
73 }
74
75 /**
Andreas Papazois827d8d02016-04-15 11:53:16 +030076 * Builds a request to add an access interface to a VLAN.
Andreas Papazois1ed54cf2016-05-04 16:22:40 +030077 *
Andreas Papazois92e4a042016-02-24 15:29:30 +020078 * @param intf the name of the interface
79 * @param vlanId the VLAN ID
80 * @return the request string.
81 */
Andreas Papazois827d8d02016-04-15 11:53:16 +030082 private String addAccessInterfaceBuilder(String intf, VlanId vlanId) {
Andreas Papazois92e4a042016-02-24 15:29:30 +020083 StringBuilder rpc =
84 new StringBuilder("<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ");
85 rpc.append("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">");
86 rpc.append("<edit-config>");
87 rpc.append("<target>");
88 rpc.append("<running/>");
89 rpc.append("</target>");
90 rpc.append("<config>");
91 rpc.append("<xml-config-data>");
92 rpc.append("<Device-Configuration><interface><Param>");
93 rpc.append(intf);
94 rpc.append("</Param>");
95 rpc.append("<ConfigIf-Configuration>");
96 rpc.append("<switchport><access><vlan><VLANIDVLANPortAccessMode>");
97 rpc.append(vlanId);
98 rpc.append("</VLANIDVLANPortAccessMode></vlan></access></switchport>");
99 rpc.append("<switchport><mode><access/></mode></switchport>");
100 rpc.append("</ConfigIf-Configuration>");
101 rpc.append("</interface>");
102 rpc.append("</Device-Configuration>");
103 rpc.append("</xml-config-data>");
104 rpc.append("</config>");
105 rpc.append("</edit-config>");
106 rpc.append("</rpc>");
107
108 return rpc.toString();
109 }
110
111 /**
Andreas Papazois827d8d02016-04-15 11:53:16 +0300112 * Removes an access interface to a VLAN.
Andreas Papazois1ed54cf2016-05-04 16:22:40 +0300113 *
Andreas Papazois92e4a042016-02-24 15:29:30 +0200114 * @param deviceId the device ID
115 * @param intf the name of the interface
Andreas Papazois92e4a042016-02-24 15:29:30 +0200116 * @return the result of operation
117 */
118 @Override
Andreas Papazois827d8d02016-04-15 11:53:16 +0300119 public boolean removeAccessInterface(DeviceId deviceId, String intf) {
Andreas Papazois92e4a042016-02-24 15:29:30 +0200120 NetconfController controller = checkNotNull(handler()
121 .get(NetconfController.class));
122
123 NetconfSession session = controller.getDevicesMap().get(handler()
124 .data().deviceId()).getSession();
125 String reply;
126 try {
Andreas Papazois827d8d02016-04-15 11:53:16 +0300127 reply = session.requestSync(removeAccessInterfaceBuilder(intf));
Andreas Papazois92e4a042016-02-24 15:29:30 +0200128 } catch (NetconfException e) {
Andreas Papazois827d8d02016-04-15 11:53:16 +0300129 log.error("Failed to remove access mode from device {} interface {}.",
130 deviceId, intf, e);
Andreas Papazois92e4a042016-02-24 15:29:30 +0200131 return false;
132 }
133
134 return XmlConfigParser.configSuccess(XmlConfigParser.loadXml(
135 new ByteArrayInputStream(reply.getBytes(StandardCharsets.UTF_8))));
136 }
137
138 /**
Andreas Papazois827d8d02016-04-15 11:53:16 +0300139 * Builds a request to remove an access interface from a VLAN.
Andreas Papazois1ed54cf2016-05-04 16:22:40 +0300140 *
Andreas Papazois92e4a042016-02-24 15:29:30 +0200141 * @param intf the name of the interface
Andreas Papazois92e4a042016-02-24 15:29:30 +0200142 * @return the request string.
143 */
Andreas Papazois827d8d02016-04-15 11:53:16 +0300144 private String removeAccessInterfaceBuilder(String intf) {
Andreas Papazois92e4a042016-02-24 15:29:30 +0200145 StringBuilder rpc =
146 new StringBuilder("<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ");
147 rpc.append("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">");
148 rpc.append("<edit-config>");
149 rpc.append("<target>");
150 rpc.append("<running/>");
151 rpc.append("</target>");
152 rpc.append("<config>");
153 rpc.append("<xml-config-data>");
154 rpc.append("<Device-Configuration><interface><Param>");
155 rpc.append(intf);
156 rpc.append("</Param>");
157 rpc.append("<ConfigIf-Configuration>");
158 rpc.append("<switchport operation=\"delete\"><access><vlan><VLANIDVLANPortAccessMode>");
Andreas Papazois92e4a042016-02-24 15:29:30 +0200159 rpc.append("</VLANIDVLANPortAccessMode></vlan></access></switchport>");
160 rpc.append("<switchport operation=\"delete\"><mode><access/></mode></switchport>");
161 rpc.append("</ConfigIf-Configuration>");
162 rpc.append("</interface>");
163 rpc.append("</Device-Configuration>");
164 rpc.append("</xml-config-data>");
165 rpc.append("</config>");
166 rpc.append("</edit-config>");
167 rpc.append("</rpc>");
168
169 return rpc.toString();
170 }
171
172 /**
Andreas Papazois827d8d02016-04-15 11:53:16 +0300173 * Adds a trunk interface for VLANs.
Andreas Papazois1ed54cf2016-05-04 16:22:40 +0300174 *
Andreas Papazois92e4a042016-02-24 15:29:30 +0200175 * @param deviceId the device ID
176 * @param intf the name of the interface
Andreas Papazois59e19bb2016-04-12 13:59:58 +0300177 * @param vlanIds the VLAN IDs
Andreas Papazois92e4a042016-02-24 15:29:30 +0200178 * @return the result of operation
179 */
180 @Override
Andreas Papazois59e19bb2016-04-12 13:59:58 +0300181 public boolean addTrunkInterface(DeviceId deviceId, String intf, List<VlanId> vlanIds) {
Andreas Papazois92e4a042016-02-24 15:29:30 +0200182 NetconfController controller = checkNotNull(handler()
183 .get(NetconfController.class));
184
185 NetconfSession session = controller.getDevicesMap().get(handler()
186 .data().deviceId()).getSession();
187 String reply;
188 try {
Andreas Papazois59e19bb2016-04-12 13:59:58 +0300189 reply = session.requestSync(addTrunkInterfaceBuilder(intf, vlanIds));
Andreas Papazois92e4a042016-02-24 15:29:30 +0200190 } catch (NetconfException e) {
191 log.error("Failed to configure trunk mode for VLAN ID {} on device {} interface {}.",
Andreas Papazois59e19bb2016-04-12 13:59:58 +0300192 vlanIds, deviceId, intf, e);
Andreas Papazois92e4a042016-02-24 15:29:30 +0200193 return false;
194 }
195
196 return XmlConfigParser.configSuccess(XmlConfigParser.loadXml(
197 new ByteArrayInputStream(reply.getBytes(StandardCharsets.UTF_8))));
198 }
199
200 /**
Andreas Papazois59e19bb2016-04-12 13:59:58 +0300201 * Builds a request to configure an interface as trunk for VLANs.
Andreas Papazois1ed54cf2016-05-04 16:22:40 +0300202 *
Andreas Papazois92e4a042016-02-24 15:29:30 +0200203 * @param intf the name of the interface
Andreas Papazois59e19bb2016-04-12 13:59:58 +0300204 * @param vlanIds the VLAN IDs
Andreas Papazois92e4a042016-02-24 15:29:30 +0200205 * @return the request string.
206 */
Andreas Papazois59e19bb2016-04-12 13:59:58 +0300207 private String addTrunkInterfaceBuilder(String intf, List<VlanId> vlanIds) {
Andreas Papazois92e4a042016-02-24 15:29:30 +0200208 StringBuilder rpc =
209 new StringBuilder("<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ");
210 rpc.append("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">");
211 rpc.append("<edit-config>");
212 rpc.append("<target>");
213 rpc.append("<running/>");
214 rpc.append("</target>");
215 rpc.append("<config>");
216 rpc.append("<xml-config-data>");
217 rpc.append("<Device-Configuration><interface><Param>");
218 rpc.append(intf);
219 rpc.append("</Param>");
220 rpc.append("<ConfigIf-Configuration>");
221 rpc.append("<switchport><trunk><encapsulation><dot1q/></encapsulation>");
222 rpc.append("</trunk></switchport><switchport><trunk><allowed><vlan>");
223 rpc.append("<VLANIDsAllowedVLANsPortTrunkingMode>");
Andreas Papazois59e19bb2016-04-12 13:59:58 +0300224 rpc.append(getVlansString(vlanIds));
Andreas Papazois92e4a042016-02-24 15:29:30 +0200225 rpc.append("</VLANIDsAllowedVLANsPortTrunkingMode></vlan></allowed></trunk>");
226 rpc.append("</switchport><switchport><mode><trunk/></mode></switchport>");
227 rpc.append("</ConfigIf-Configuration>");
228 rpc.append("</interface>");
229 rpc.append("</Device-Configuration>");
230 rpc.append("</xml-config-data>");
231 rpc.append("</config>");
232 rpc.append("</edit-config>");
233 rpc.append("</rpc>");
234
235 return rpc.toString();
236 }
237
238 /**
Andreas Papazois1ed54cf2016-05-04 16:22:40 +0300239 * Removes trunk mode configuration from an interface.
240 *
Andreas Papazois92e4a042016-02-24 15:29:30 +0200241 * @param deviceId the device ID
242 * @param intf the name of the interface
Andreas Papazois92e4a042016-02-24 15:29:30 +0200243 * @return the result of operation
244 */
245 @Override
Andreas Papazois827d8d02016-04-15 11:53:16 +0300246 public boolean removeTrunkInterface(DeviceId deviceId, String intf) {
Andreas Papazois92e4a042016-02-24 15:29:30 +0200247 NetconfController controller = checkNotNull(handler()
248 .get(NetconfController.class));
249
250 NetconfSession session = controller.getDevicesMap().get(handler()
251 .data().deviceId()).getSession();
252 String reply;
253 try {
Andreas Papazois827d8d02016-04-15 11:53:16 +0300254 reply = session.requestSync(removeTrunkInterfaceBuilder(intf));
Andreas Papazois92e4a042016-02-24 15:29:30 +0200255 } catch (NetconfException e) {
Andreas Papazois827d8d02016-04-15 11:53:16 +0300256 log.error("Failed to remove trunk mode on device {} interface {}.",
257 deviceId, intf, e);
Andreas Papazois92e4a042016-02-24 15:29:30 +0200258 return false;
259 }
260
261 return XmlConfigParser.configSuccess(XmlConfigParser.loadXml(
262 new ByteArrayInputStream(reply.getBytes(StandardCharsets.UTF_8))));
263}
264
265 /**
Andreas Papazois827d8d02016-04-15 11:53:16 +0300266 * Builds a request to remove trunk mode configuration from an interface.
Andreas Papazois1ed54cf2016-05-04 16:22:40 +0300267 *
Andreas Papazois92e4a042016-02-24 15:29:30 +0200268 * @param intf the name of the interface
Andreas Papazois92e4a042016-02-24 15:29:30 +0200269 * @return the request string.
270 */
Andreas Papazois827d8d02016-04-15 11:53:16 +0300271 private String removeTrunkInterfaceBuilder(String intf) {
Andreas Papazois92e4a042016-02-24 15:29:30 +0200272 StringBuilder rpc =
273 new StringBuilder("<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ");
274 rpc.append("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">");
275 rpc.append("<edit-config>");
276 rpc.append("<target>");
277 rpc.append("<running/>");
278 rpc.append("</target>");
279 rpc.append("<config>");
280 rpc.append("<xml-config-data>");
281 rpc.append("<Device-Configuration><interface><Param>");
282 rpc.append(intf);
283 rpc.append("</Param>");
284 rpc.append("<ConfigIf-Configuration>");
285 rpc.append("<switchport><mode operation=\"delete\"><trunk/></mode></switchport>");
286 rpc.append("<switchport><trunk operation=\"delete\"><encapsulation>");
287 rpc.append("<dot1q/></encapsulation></trunk></switchport>");
288 rpc.append("<switchport><trunk operation=\"delete\"><allowed><vlan>");
289 rpc.append("<VLANIDsAllowedVLANsPortTrunkingMode>");
Andreas Papazois92e4a042016-02-24 15:29:30 +0200290 rpc.append("</VLANIDsAllowedVLANsPortTrunkingMode></vlan></allowed>");
291 rpc.append("</trunk></switchport></ConfigIf-Configuration>");
292 rpc.append("</interface>");
293 rpc.append("</Device-Configuration>");
294 rpc.append("</xml-config-data>");
295 rpc.append("</config>");
296 rpc.append("</edit-config>");
297 rpc.append("</rpc>");
298
299 return rpc.toString();
300 }
301
Andreas Papazois59e19bb2016-04-12 13:59:58 +0300302 /**
303 * Builds a string with comma separated VLAN-IDs.
Andreas Papazois1ed54cf2016-05-04 16:22:40 +0300304 *
Andreas Papazois59e19bb2016-04-12 13:59:58 +0300305 * @param vlanIds the VLAN IDs
306 * @return the string including the VLAN-IDs
307 */
308 private String getVlansString(List<VlanId> vlanIds) {
309 StringBuilder vlansStringBuilder = new StringBuilder();
310
311 for (int i = 0; i < vlanIds.size(); i++) {
312 vlansStringBuilder.append(vlanIds.get(i));
313
314 if (i != vlanIds.size() - 1) {
315 vlansStringBuilder.append(",");
316 }
317 }
318 return vlansStringBuilder.toString();
319 }
320
Andreas Papazois1ed54cf2016-05-04 16:22:40 +0300321 /**
322 * Provides the interfaces configured on a device.
323 *
324 * @param deviceId the device ID
325 * @return the list of the configured interfaces
326 */
327 @Override
328 public List<DeviceInterfaceDescription> getInterfaces(DeviceId deviceId) {
329 NetconfController controller =
330 checkNotNull(handler().get(NetconfController.class));
331
332 NetconfSession session = controller.getDevicesMap().get(handler()
333 .data().deviceId()).getSession();
334 String reply;
335 try {
336 reply = session.requestSync(getConfigBuilder());
337 } catch (NetconfException e) {
338 log.error("Failed to retrieve configuration from device {}.",
339 deviceId, e);
340 return null;
341 }
342
343 return XmlParserCisco.getInterfacesFromConfig(XmlConfigParser.loadXml(
344 new ByteArrayInputStream(reply.getBytes(StandardCharsets.UTF_8))));
345 }
346
347 /**
348 * Builds a request for getting configuration from device.
349 *
350 * @return the request string.
351 */
352 private String getConfigBuilder() {
353 StringBuilder rpc =
354 new StringBuilder("<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ");
355 rpc.append("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">");
356 rpc.append("<get-config>");
357 rpc.append("<source>");
358 rpc.append("<running/>");
359 rpc.append("</source>");
360 rpc.append("<filter>");
361 rpc.append("<config-format-xml>");
362 rpc.append("</config-format-xml>");
363 rpc.append("</filter>");
364 rpc.append("</get-config>");
365 rpc.append("</rpc>");
366
367 return rpc.toString();
368 }
369
Andreas Papazois92e4a042016-02-24 15:29:30 +0200370}
371