Committed by
Gerrit Code Review
Command using VlanQuery behavior on device.
Change-Id: Ifef86810d1f8bf8b59a1e9ba2735cd79bfb890f7
Showing
2 changed files
with
171 additions
and
0 deletions
1 | +/* | ||
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 | + */ | ||
16 | +package org.onosproject.cli.net; | ||
17 | + | ||
18 | +import org.apache.karaf.shell.commands.Argument; | ||
19 | +import org.apache.karaf.shell.commands.Command; | ||
20 | +import org.onlab.packet.VlanId; | ||
21 | +import org.onosproject.cli.AbstractShellCommand; | ||
22 | +import org.onosproject.net.ConnectPoint; | ||
23 | +import org.onosproject.net.Device; | ||
24 | +import org.onosproject.net.DeviceId; | ||
25 | +import org.onosproject.net.Port; | ||
26 | +import org.onosproject.net.PortNumber; | ||
27 | +import org.onosproject.net.behaviour.VlanQuery; | ||
28 | +import org.onosproject.net.device.DeviceService; | ||
29 | +import org.onosproject.net.driver.DriverHandler; | ||
30 | +import org.onosproject.net.driver.DriverService; | ||
31 | + | ||
32 | +import java.util.ArrayList; | ||
33 | +import java.util.Arrays; | ||
34 | +import java.util.Set; | ||
35 | + | ||
36 | +/** | ||
37 | + * Command to show the list of unused vlan-ids. | ||
38 | + */ | ||
39 | +@Command(scope = "onos", name = "port-query-vlans", | ||
40 | + description = "Lists all unused VLAN-IDs on port") | ||
41 | +public class PortQueryVlansCommand extends AbstractShellCommand { | ||
42 | + | ||
43 | + private static final String AVAIL_VLANS = "VLAN-ID: %s"; | ||
44 | + private static final String VLAN_NOT_AVAILABLE = "No unused VLAN-ID"; | ||
45 | + private static final String FMT = "port=%s, state=%s, type=%s, speed=%s%s"; | ||
46 | + private static final String NO_SUPPORT = "Device not supporting VLAN-ID retrieval"; | ||
47 | + private static final String FAILURE = "Failed to retrieve VLAN information: "; | ||
48 | + | ||
49 | + @Argument(index = 0, name = "port", | ||
50 | + description = "Port Description", | ||
51 | + required = true, multiValued = true) | ||
52 | + private String[] ports; | ||
53 | + | ||
54 | + | ||
55 | + @Override | ||
56 | + protected void execute() { | ||
57 | + DeviceService service = get(DeviceService.class); | ||
58 | + for (String portStr : ports) { | ||
59 | + ConnectPoint connectPoint = ConnectPoint.deviceConnectPoint(portStr); | ||
60 | + Port port = service.getPort(connectPoint.deviceId(), connectPoint.port()); | ||
61 | + printPort(port); | ||
62 | + printVlans(port); | ||
63 | + } | ||
64 | + } | ||
65 | + | ||
66 | + private void printPort(Port port) { | ||
67 | + String portName = portName(port.number()); | ||
68 | + Object portIsEnabled = port.isEnabled() ? "enabled" : "disabled"; | ||
69 | + String portType = port.type().toString().toLowerCase(); | ||
70 | + String annotations = annotations(port.annotations()); | ||
71 | + print(FMT, portName, portIsEnabled, portType, port.portSpeed(), annotations); | ||
72 | + } | ||
73 | + | ||
74 | + private String portName(PortNumber port) { | ||
75 | + return port.equals(PortNumber.LOCAL) ? "local" : port.toString(); | ||
76 | + } | ||
77 | + | ||
78 | + private void printVlans(Port port) { | ||
79 | + DeviceService deviceService = get(DeviceService.class); | ||
80 | + DriverService driverService = get(DriverService.class); | ||
81 | + | ||
82 | + DeviceId deviceId = (DeviceId) port.element().id(); | ||
83 | + Device device = deviceService.getDevice(deviceId); | ||
84 | + | ||
85 | + if (!device.is(VlanQuery.class)) { | ||
86 | + // The relevant behavior is not supported by the device. | ||
87 | + print(NO_SUPPORT); | ||
88 | + return; | ||
89 | + } | ||
90 | + | ||
91 | + DriverHandler h = driverService.createHandler(deviceId); | ||
92 | + VlanQuery vlanQuery = h.behaviour(VlanQuery.class); | ||
93 | + | ||
94 | + try { | ||
95 | + Set<VlanId> vlanIds = vlanQuery.queryVlanIds(port.number()); | ||
96 | + | ||
97 | + if (vlanIds.isEmpty()) { | ||
98 | + print(VLAN_NOT_AVAILABLE); | ||
99 | + } else { | ||
100 | + print(AVAIL_VLANS, getRanges(vlanIds).toString()); | ||
101 | + } | ||
102 | + } catch (Exception e) { | ||
103 | + print(FAILURE + e.getMessage()); | ||
104 | + } | ||
105 | + } | ||
106 | + | ||
107 | + private static ArrayList getRanges(Set<VlanId> vlans) { | ||
108 | + short i = 0; | ||
109 | + short[] vlanArray = new short[vlans.size()]; | ||
110 | + for (VlanId vlanId : vlans) { | ||
111 | + vlanArray[i++] = vlanId.toShort(); | ||
112 | + } | ||
113 | + Arrays.sort(vlanArray); | ||
114 | + | ||
115 | + ArrayList ranges = new ArrayList(); | ||
116 | + short rStart = 0; | ||
117 | + short rEnd = 0; | ||
118 | + | ||
119 | + for (i = 2; i < vlanArray.length; i++) { | ||
120 | + if (vlanArray[i] == vlanArray[i - 1] + 1 && | ||
121 | + vlanArray[i] == vlanArray[i - 2] + 2) { | ||
122 | + // Three consecutive VLAN-IDs found, so range exists. | ||
123 | + if (rEnd == vlanArray[i - 1]) { | ||
124 | + // Range already exists, so step the end. | ||
125 | + rEnd = vlanArray[i]; | ||
126 | + } else { | ||
127 | + // Setup a new range. | ||
128 | + rStart = vlanArray[i - 2]; | ||
129 | + rEnd = vlanArray[i]; | ||
130 | + } | ||
131 | + } else { | ||
132 | + // Not in a range. | ||
133 | + if (rEnd == vlanArray[i - 1]) { | ||
134 | + // Previous range is discontinued and is stored. | ||
135 | + ranges.add(rStart + "-" + rEnd); | ||
136 | + } else { | ||
137 | + // No previous range. | ||
138 | + if (vlanArray[i] != vlanArray[i - 1] + 1) { | ||
139 | + // Current VLAN-ID is not 2nd consecutive. | ||
140 | + if (vlanArray[i - 1] == vlanArray[i - 2] + 1) { | ||
141 | + // The 2 previous VLAN-IDs were consequetive, so 2nd | ||
142 | + // last is stored separately. | ||
143 | + ranges.add(vlanArray[i - 2]); | ||
144 | + } | ||
145 | + // Previous is stored, when current is not consequetive. | ||
146 | + ranges.add(vlanArray[i - 1]); | ||
147 | + } | ||
148 | + } | ||
149 | + } | ||
150 | + } | ||
151 | + if (rEnd == vlanArray[vlanArray.length - 1]) { | ||
152 | + // Array finished with a range. | ||
153 | + ranges.add(rStart + "-" + rEnd); | ||
154 | + } else { | ||
155 | + if (vlanArray[vlanArray.length - 1] == vlanArray[vlanArray.length - 2] + 1) { | ||
156 | + // Previous is stored, when current is consequetive. | ||
157 | + ranges.add(vlanArray[vlanArray.length - 2]); | ||
158 | + } | ||
159 | + // Last item is stored | ||
160 | + ranges.add(vlanArray[vlanArray.length - 1]); | ||
161 | + } | ||
162 | + return ranges; | ||
163 | + } | ||
164 | +} |
... | @@ -463,6 +463,13 @@ | ... | @@ -463,6 +463,13 @@ |
463 | </command> | 463 | </command> |
464 | 464 | ||
465 | <command> | 465 | <command> |
466 | + <action class="org.onosproject.cli.net.PortQueryVlansCommand"/> | ||
467 | + <completers> | ||
468 | + <ref component-id="connectPointCompleter"/> | ||
469 | + </completers> | ||
470 | + </command> | ||
471 | + | ||
472 | + <command> | ||
466 | <action class="org.onosproject.cli.net.TableStatisticsCommand"/> | 473 | <action class="org.onosproject.cli.net.TableStatisticsCommand"/> |
467 | </command> | 474 | </command> |
468 | 475 | ... | ... |
-
Please register or login to post a comment