blob: a8259a8613db09af3661e8ac0ddcd937f92a10d0 [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;
25import org.onosproject.net.driver.AbstractHandlerBehaviour;
26import org.onosproject.netconf.NetconfController;
27import org.onosproject.netconf.NetconfException;
28import org.onosproject.netconf.NetconfSession;
29import org.slf4j.Logger;
30
31import java.io.ByteArrayInputStream;
32import java.nio.charset.StandardCharsets;
Andreas Papazois59e19bb2016-04-12 13:59:58 +030033import java.util.List;
Andreas Papazois92e4a042016-02-24 15:29:30 +020034
35import static com.google.common.base.Preconditions.checkNotNull;
36import static org.slf4j.LoggerFactory.getLogger;
37
38/**
39 * Configures interfaces on Cisco IOS devices.
40 */
41public class InterfaceConfigCiscoIosImpl extends AbstractHandlerBehaviour
42 implements InterfaceConfig {
43
44 private final Logger log = getLogger(getClass());
45
46 /**
Andreas Papazois827d8d02016-04-15 11:53:16 +030047 * Adds an access interface to a VLAN.
Andreas Papazois92e4a042016-02-24 15:29:30 +020048 * @param deviceId the device ID
49 * @param intf the name of the interface
50 * @param vlanId the VLAN ID
51 * @return the result of operation
52 */
53 @Override
Andreas Papazois827d8d02016-04-15 11:53:16 +030054 public boolean addAccessInterface(DeviceId deviceId, String intf, VlanId vlanId) {
Andreas Papazois92e4a042016-02-24 15:29:30 +020055 NetconfController controller = checkNotNull(handler()
56 .get(NetconfController.class));
57
58 NetconfSession session = controller.getDevicesMap().get(handler()
59 .data().deviceId()).getSession();
60 String reply;
61 try {
Andreas Papazois827d8d02016-04-15 11:53:16 +030062 reply = session.requestSync(addAccessInterfaceBuilder(intf, vlanId));
Andreas Papazois92e4a042016-02-24 15:29:30 +020063 } catch (NetconfException e) {
64 log.error("Failed to configure VLAN ID {} on device {} interface {}.",
65 vlanId, deviceId, intf, e);
66 return false;
67 }
68
69 return XmlConfigParser.configSuccess(XmlConfigParser.loadXml(
70 new ByteArrayInputStream(reply.getBytes(StandardCharsets.UTF_8))));
71 }
72
73 /**
Andreas Papazois827d8d02016-04-15 11:53:16 +030074 * Builds a request to add an access interface to a VLAN.
Andreas Papazois92e4a042016-02-24 15:29:30 +020075 * @param intf the name of the interface
76 * @param vlanId the VLAN ID
77 * @return the request string.
78 */
Andreas Papazois827d8d02016-04-15 11:53:16 +030079 private String addAccessInterfaceBuilder(String intf, VlanId vlanId) {
Andreas Papazois92e4a042016-02-24 15:29:30 +020080 StringBuilder rpc =
81 new StringBuilder("<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ");
82 rpc.append("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">");
83 rpc.append("<edit-config>");
84 rpc.append("<target>");
85 rpc.append("<running/>");
86 rpc.append("</target>");
87 rpc.append("<config>");
88 rpc.append("<xml-config-data>");
89 rpc.append("<Device-Configuration><interface><Param>");
90 rpc.append(intf);
91 rpc.append("</Param>");
92 rpc.append("<ConfigIf-Configuration>");
93 rpc.append("<switchport><access><vlan><VLANIDVLANPortAccessMode>");
94 rpc.append(vlanId);
95 rpc.append("</VLANIDVLANPortAccessMode></vlan></access></switchport>");
96 rpc.append("<switchport><mode><access/></mode></switchport>");
97 rpc.append("</ConfigIf-Configuration>");
98 rpc.append("</interface>");
99 rpc.append("</Device-Configuration>");
100 rpc.append("</xml-config-data>");
101 rpc.append("</config>");
102 rpc.append("</edit-config>");
103 rpc.append("</rpc>");
104
105 return rpc.toString();
106 }
107
108 /**
Andreas Papazois827d8d02016-04-15 11:53:16 +0300109 * Removes an access interface to a VLAN.
Andreas Papazois92e4a042016-02-24 15:29:30 +0200110 * @param deviceId the device ID
111 * @param intf the name of the interface
Andreas Papazois92e4a042016-02-24 15:29:30 +0200112 * @return the result of operation
113 */
114 @Override
Andreas Papazois827d8d02016-04-15 11:53:16 +0300115 public boolean removeAccessInterface(DeviceId deviceId, String intf) {
Andreas Papazois92e4a042016-02-24 15:29:30 +0200116 NetconfController controller = checkNotNull(handler()
117 .get(NetconfController.class));
118
119 NetconfSession session = controller.getDevicesMap().get(handler()
120 .data().deviceId()).getSession();
121 String reply;
122 try {
Andreas Papazois827d8d02016-04-15 11:53:16 +0300123 reply = session.requestSync(removeAccessInterfaceBuilder(intf));
Andreas Papazois92e4a042016-02-24 15:29:30 +0200124 } catch (NetconfException e) {
Andreas Papazois827d8d02016-04-15 11:53:16 +0300125 log.error("Failed to remove access mode from device {} interface {}.",
126 deviceId, intf, e);
Andreas Papazois92e4a042016-02-24 15:29:30 +0200127 return false;
128 }
129
130 return XmlConfigParser.configSuccess(XmlConfigParser.loadXml(
131 new ByteArrayInputStream(reply.getBytes(StandardCharsets.UTF_8))));
132 }
133
134 /**
Andreas Papazois827d8d02016-04-15 11:53:16 +0300135 * Builds a request to remove an access interface from a VLAN.
Andreas Papazois92e4a042016-02-24 15:29:30 +0200136 * @param intf the name of the interface
Andreas Papazois92e4a042016-02-24 15:29:30 +0200137 * @return the request string.
138 */
Andreas Papazois827d8d02016-04-15 11:53:16 +0300139 private String removeAccessInterfaceBuilder(String intf) {
Andreas Papazois92e4a042016-02-24 15:29:30 +0200140 StringBuilder rpc =
141 new StringBuilder("<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ");
142 rpc.append("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">");
143 rpc.append("<edit-config>");
144 rpc.append("<target>");
145 rpc.append("<running/>");
146 rpc.append("</target>");
147 rpc.append("<config>");
148 rpc.append("<xml-config-data>");
149 rpc.append("<Device-Configuration><interface><Param>");
150 rpc.append(intf);
151 rpc.append("</Param>");
152 rpc.append("<ConfigIf-Configuration>");
153 rpc.append("<switchport operation=\"delete\"><access><vlan><VLANIDVLANPortAccessMode>");
Andreas Papazois92e4a042016-02-24 15:29:30 +0200154 rpc.append("</VLANIDVLANPortAccessMode></vlan></access></switchport>");
155 rpc.append("<switchport operation=\"delete\"><mode><access/></mode></switchport>");
156 rpc.append("</ConfigIf-Configuration>");
157 rpc.append("</interface>");
158 rpc.append("</Device-Configuration>");
159 rpc.append("</xml-config-data>");
160 rpc.append("</config>");
161 rpc.append("</edit-config>");
162 rpc.append("</rpc>");
163
164 return rpc.toString();
165 }
166
167 /**
Andreas Papazois827d8d02016-04-15 11:53:16 +0300168 * Adds a trunk interface for VLANs.
Andreas Papazois92e4a042016-02-24 15:29:30 +0200169 * @param deviceId the device ID
170 * @param intf the name of the interface
Andreas Papazois59e19bb2016-04-12 13:59:58 +0300171 * @param vlanIds the VLAN IDs
Andreas Papazois92e4a042016-02-24 15:29:30 +0200172 * @return the result of operation
173 */
174 @Override
Andreas Papazois59e19bb2016-04-12 13:59:58 +0300175 public boolean addTrunkInterface(DeviceId deviceId, String intf, List<VlanId> vlanIds) {
Andreas Papazois92e4a042016-02-24 15:29:30 +0200176 NetconfController controller = checkNotNull(handler()
177 .get(NetconfController.class));
178
179 NetconfSession session = controller.getDevicesMap().get(handler()
180 .data().deviceId()).getSession();
181 String reply;
182 try {
Andreas Papazois59e19bb2016-04-12 13:59:58 +0300183 reply = session.requestSync(addTrunkInterfaceBuilder(intf, vlanIds));
Andreas Papazois92e4a042016-02-24 15:29:30 +0200184 } catch (NetconfException e) {
185 log.error("Failed to configure trunk mode for VLAN ID {} on device {} interface {}.",
Andreas Papazois59e19bb2016-04-12 13:59:58 +0300186 vlanIds, deviceId, intf, e);
Andreas Papazois92e4a042016-02-24 15:29:30 +0200187 return false;
188 }
189
190 return XmlConfigParser.configSuccess(XmlConfigParser.loadXml(
191 new ByteArrayInputStream(reply.getBytes(StandardCharsets.UTF_8))));
192 }
193
194 /**
Andreas Papazois59e19bb2016-04-12 13:59:58 +0300195 * Builds a request to configure an interface as trunk for VLANs.
Andreas Papazois92e4a042016-02-24 15:29:30 +0200196 * @param intf the name of the interface
Andreas Papazois59e19bb2016-04-12 13:59:58 +0300197 * @param vlanIds the VLAN IDs
Andreas Papazois92e4a042016-02-24 15:29:30 +0200198 * @return the request string.
199 */
Andreas Papazois59e19bb2016-04-12 13:59:58 +0300200 private String addTrunkInterfaceBuilder(String intf, List<VlanId> vlanIds) {
Andreas Papazois92e4a042016-02-24 15:29:30 +0200201 StringBuilder rpc =
202 new StringBuilder("<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ");
203 rpc.append("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">");
204 rpc.append("<edit-config>");
205 rpc.append("<target>");
206 rpc.append("<running/>");
207 rpc.append("</target>");
208 rpc.append("<config>");
209 rpc.append("<xml-config-data>");
210 rpc.append("<Device-Configuration><interface><Param>");
211 rpc.append(intf);
212 rpc.append("</Param>");
213 rpc.append("<ConfigIf-Configuration>");
214 rpc.append("<switchport><trunk><encapsulation><dot1q/></encapsulation>");
215 rpc.append("</trunk></switchport><switchport><trunk><allowed><vlan>");
216 rpc.append("<VLANIDsAllowedVLANsPortTrunkingMode>");
Andreas Papazois59e19bb2016-04-12 13:59:58 +0300217 rpc.append(getVlansString(vlanIds));
Andreas Papazois92e4a042016-02-24 15:29:30 +0200218 rpc.append("</VLANIDsAllowedVLANsPortTrunkingMode></vlan></allowed></trunk>");
219 rpc.append("</switchport><switchport><mode><trunk/></mode></switchport>");
220 rpc.append("</ConfigIf-Configuration>");
221 rpc.append("</interface>");
222 rpc.append("</Device-Configuration>");
223 rpc.append("</xml-config-data>");
224 rpc.append("</config>");
225 rpc.append("</edit-config>");
226 rpc.append("</rpc>");
227
228 return rpc.toString();
229 }
230
231 /**
Andreas Papazois827d8d02016-04-15 11:53:16 +0300232 * Removes trunk mode configuration from an interface.
Andreas Papazois92e4a042016-02-24 15:29:30 +0200233 * @param deviceId the device ID
234 * @param intf the name of the interface
Andreas Papazois92e4a042016-02-24 15:29:30 +0200235 * @return the result of operation
236 */
237 @Override
Andreas Papazois827d8d02016-04-15 11:53:16 +0300238 public boolean removeTrunkInterface(DeviceId deviceId, String intf) {
Andreas Papazois92e4a042016-02-24 15:29:30 +0200239 NetconfController controller = checkNotNull(handler()
240 .get(NetconfController.class));
241
242 NetconfSession session = controller.getDevicesMap().get(handler()
243 .data().deviceId()).getSession();
244 String reply;
245 try {
Andreas Papazois827d8d02016-04-15 11:53:16 +0300246 reply = session.requestSync(removeTrunkInterfaceBuilder(intf));
Andreas Papazois92e4a042016-02-24 15:29:30 +0200247 } catch (NetconfException e) {
Andreas Papazois827d8d02016-04-15 11:53:16 +0300248 log.error("Failed to remove trunk mode on device {} interface {}.",
249 deviceId, intf, e);
Andreas Papazois92e4a042016-02-24 15:29:30 +0200250 return false;
251 }
252
253 return XmlConfigParser.configSuccess(XmlConfigParser.loadXml(
254 new ByteArrayInputStream(reply.getBytes(StandardCharsets.UTF_8))));
255}
256
257 /**
Andreas Papazois827d8d02016-04-15 11:53:16 +0300258 * Builds a request to remove trunk mode configuration from an interface.
Andreas Papazois92e4a042016-02-24 15:29:30 +0200259 * @param intf the name of the interface
Andreas Papazois92e4a042016-02-24 15:29:30 +0200260 * @return the request string.
261 */
Andreas Papazois827d8d02016-04-15 11:53:16 +0300262 private String removeTrunkInterfaceBuilder(String intf) {
Andreas Papazois92e4a042016-02-24 15:29:30 +0200263 StringBuilder rpc =
264 new StringBuilder("<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ");
265 rpc.append("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">");
266 rpc.append("<edit-config>");
267 rpc.append("<target>");
268 rpc.append("<running/>");
269 rpc.append("</target>");
270 rpc.append("<config>");
271 rpc.append("<xml-config-data>");
272 rpc.append("<Device-Configuration><interface><Param>");
273 rpc.append(intf);
274 rpc.append("</Param>");
275 rpc.append("<ConfigIf-Configuration>");
276 rpc.append("<switchport><mode operation=\"delete\"><trunk/></mode></switchport>");
277 rpc.append("<switchport><trunk operation=\"delete\"><encapsulation>");
278 rpc.append("<dot1q/></encapsulation></trunk></switchport>");
279 rpc.append("<switchport><trunk operation=\"delete\"><allowed><vlan>");
280 rpc.append("<VLANIDsAllowedVLANsPortTrunkingMode>");
Andreas Papazois92e4a042016-02-24 15:29:30 +0200281 rpc.append("</VLANIDsAllowedVLANsPortTrunkingMode></vlan></allowed>");
282 rpc.append("</trunk></switchport></ConfigIf-Configuration>");
283 rpc.append("</interface>");
284 rpc.append("</Device-Configuration>");
285 rpc.append("</xml-config-data>");
286 rpc.append("</config>");
287 rpc.append("</edit-config>");
288 rpc.append("</rpc>");
289
290 return rpc.toString();
291 }
292
Andreas Papazois59e19bb2016-04-12 13:59:58 +0300293 /**
294 * Builds a string with comma separated VLAN-IDs.
295 * @param vlanIds the VLAN IDs
296 * @return the string including the VLAN-IDs
297 */
298 private String getVlansString(List<VlanId> vlanIds) {
299 StringBuilder vlansStringBuilder = new StringBuilder();
300
301 for (int i = 0; i < vlanIds.size(); i++) {
302 vlansStringBuilder.append(vlanIds.get(i));
303
304 if (i != vlanIds.size() - 1) {
305 vlansStringBuilder.append(",");
306 }
307 }
308 return vlansStringBuilder.toString();
309 }
310
Andreas Papazois92e4a042016-02-24 15:29:30 +0200311}
312