flows cmd pretty print
Change-Id: I29b0971a5a862c602f8cd36f864f173c6d8330d6
Showing
8 changed files
with
138 additions
and
27 deletions
1 | package org.onlab.onos.cli.net; | 1 | package org.onlab.onos.cli.net; |
2 | 2 | ||
3 | -import com.google.common.collect.Maps; | 3 | +import static com.google.common.collect.Lists.newArrayList; |
4 | + | ||
5 | +import java.util.Collections; | ||
6 | +import java.util.List; | ||
7 | +import java.util.Map; | ||
8 | + | ||
9 | +import org.apache.karaf.shell.commands.Argument; | ||
4 | import org.apache.karaf.shell.commands.Command; | 10 | import org.apache.karaf.shell.commands.Command; |
5 | import org.onlab.onos.cli.AbstractShellCommand; | 11 | import org.onlab.onos.cli.AbstractShellCommand; |
6 | import org.onlab.onos.net.Device; | 12 | import org.onlab.onos.net.Device; |
13 | +import org.onlab.onos.net.DeviceId; | ||
7 | import org.onlab.onos.net.device.DeviceService; | 14 | import org.onlab.onos.net.device.DeviceService; |
8 | import org.onlab.onos.net.flow.FlowRule; | 15 | import org.onlab.onos.net.flow.FlowRule; |
16 | +import org.onlab.onos.net.flow.FlowRule.FlowRuleState; | ||
9 | import org.onlab.onos.net.flow.FlowRuleService; | 17 | import org.onlab.onos.net.flow.FlowRuleService; |
10 | 18 | ||
11 | -import java.util.Collections; | 19 | +import com.google.common.collect.Maps; |
12 | -import java.util.List; | ||
13 | -import java.util.Map; | ||
14 | - | ||
15 | -import static com.google.common.collect.Lists.newArrayList; | ||
16 | 20 | ||
17 | /** | 21 | /** |
18 | * Lists all currently-known hosts. | 22 | * Lists all currently-known hosts. |
... | @@ -22,14 +26,24 @@ description = "Lists all currently-known flows.") | ... | @@ -22,14 +26,24 @@ description = "Lists all currently-known flows.") |
22 | public class FlowsListCommand extends AbstractShellCommand { | 26 | public class FlowsListCommand extends AbstractShellCommand { |
23 | 27 | ||
24 | private static final String FMT = | 28 | private static final String FMT = |
25 | - " id=%s, selector=%s, treatment=%s, state=%s"; | 29 | + " id=%s, state=%s, bytes=%s, packets=%s, duration=%s, priority=%s"; |
30 | + private static final String TFMT = " treatment=%s"; | ||
31 | + private static final String SFMT = " selector=%s"; | ||
32 | + | ||
33 | + @Argument(index = 0, name = "state", description = "Flow rule state", | ||
34 | + required = false, multiValued = false) | ||
35 | + FlowRuleState state = null; | ||
36 | + | ||
37 | + @Argument(index = 1, name = "uri", description = "Device ID", | ||
38 | + required = false, multiValued = false) | ||
39 | + String uri = null; | ||
26 | 40 | ||
27 | @Override | 41 | @Override |
28 | protected void execute() { | 42 | protected void execute() { |
29 | DeviceService deviceService = get(DeviceService.class); | 43 | DeviceService deviceService = get(DeviceService.class); |
30 | FlowRuleService service = get(FlowRuleService.class); | 44 | FlowRuleService service = get(FlowRuleService.class); |
31 | Map<Device, List<FlowRule>> flows = getSortedFlows(deviceService, service); | 45 | Map<Device, List<FlowRule>> flows = getSortedFlows(deviceService, service); |
32 | - for (Device d : deviceService.getDevices()) { | 46 | + for (Device d : flows.keySet()) { |
33 | printFlows(d, flows.get(d)); | 47 | printFlows(d, flows.get(d)); |
34 | } | 48 | } |
35 | } | 49 | } |
... | @@ -42,8 +56,10 @@ public class FlowsListCommand extends AbstractShellCommand { | ... | @@ -42,8 +56,10 @@ public class FlowsListCommand extends AbstractShellCommand { |
42 | */ | 56 | */ |
43 | protected Map<Device, List<FlowRule>> getSortedFlows(DeviceService deviceService, FlowRuleService service) { | 57 | protected Map<Device, List<FlowRule>> getSortedFlows(DeviceService deviceService, FlowRuleService service) { |
44 | Map<Device, List<FlowRule>> flows = Maps.newHashMap(); | 58 | Map<Device, List<FlowRule>> flows = Maps.newHashMap(); |
45 | - List<FlowRule> rules; | 59 | + List<FlowRule> rules = newArrayList(); |
46 | - for (Device d : deviceService.getDevices()) { | 60 | + Iterable<Device> devices = uri == null ? deviceService.getDevices() : |
61 | + Collections.singletonList(deviceService.getDevice(DeviceId.deviceId(uri))); | ||
62 | + for (Device d : devices) { | ||
47 | rules = newArrayList(service.getFlowEntries(d.id())); | 63 | rules = newArrayList(service.getFlowEntries(d.id())); |
48 | Collections.sort(rules, Comparators.FLOW_RULE_COMPARATOR); | 64 | Collections.sort(rules, Comparators.FLOW_RULE_COMPARATOR); |
49 | flows.put(d, rules); | 65 | flows.put(d, rules); |
... | @@ -58,8 +74,15 @@ public class FlowsListCommand extends AbstractShellCommand { | ... | @@ -58,8 +74,15 @@ public class FlowsListCommand extends AbstractShellCommand { |
58 | */ | 74 | */ |
59 | protected void printFlows(Device d, List<FlowRule> flows) { | 75 | protected void printFlows(Device d, List<FlowRule> flows) { |
60 | print("Device: " + d.id()); | 76 | print("Device: " + d.id()); |
77 | + if (flows == null | flows.isEmpty()) { | ||
78 | + print(" %s", "No flows installed."); | ||
79 | + return; | ||
80 | + } | ||
61 | for (FlowRule f : flows) { | 81 | for (FlowRule f : flows) { |
62 | - print(FMT, f.id().value(), f.selector(), f.treatment(), f.state()); | 82 | + print(FMT, Long.toHexString(f.id().value()), f.state(), f.bytes(), |
83 | + f.packets(), f.lifeMillis(), f.priority()); | ||
84 | + print(SFMT, f.selector().criteria()); | ||
85 | + print(TFMT, f.treatment().instructions()); | ||
63 | } | 86 | } |
64 | 87 | ||
65 | } | 88 | } | ... | ... |
1 | package org.onlab.onos.cli.net; | 1 | package org.onlab.onos.cli.net; |
2 | 2 | ||
3 | +import java.util.Iterator; | ||
4 | +import java.util.List; | ||
5 | +import java.util.SortedSet; | ||
6 | + | ||
3 | import org.apache.karaf.shell.console.Completer; | 7 | import org.apache.karaf.shell.console.Completer; |
4 | import org.apache.karaf.shell.console.completer.StringsCompleter; | 8 | import org.apache.karaf.shell.console.completer.StringsCompleter; |
5 | import org.onlab.onos.cli.AbstractShellCommand; | 9 | import org.onlab.onos.cli.AbstractShellCommand; |
6 | import org.onlab.onos.net.Host; | 10 | import org.onlab.onos.net.Host; |
7 | import org.onlab.onos.net.host.HostService; | 11 | import org.onlab.onos.net.host.HostService; |
8 | 12 | ||
9 | -import java.util.Iterator; | ||
10 | -import java.util.List; | ||
11 | -import java.util.SortedSet; | ||
12 | - | ||
13 | public class HostIdCompleter implements Completer { | 13 | public class HostIdCompleter implements Completer { |
14 | 14 | ||
15 | @Override | 15 | @Override | ... | ... |
... | @@ -72,6 +72,9 @@ | ... | @@ -72,6 +72,9 @@ |
72 | 72 | ||
73 | <command> | 73 | <command> |
74 | <action class="org.onlab.onos.cli.net.FlowsListCommand"/> | 74 | <action class="org.onlab.onos.cli.net.FlowsListCommand"/> |
75 | + <completers> | ||
76 | + <ref component-id="deviceIdCompleter"/> | ||
77 | + </completers> | ||
75 | </command> | 78 | </command> |
76 | 79 | ||
77 | <command> | 80 | <command> | ... | ... |
1 | package org.onlab.onos.net.flow.criteria; | 1 | package org.onlab.onos.net.flow.criteria; |
2 | 2 | ||
3 | +import static com.google.common.base.MoreObjects.toStringHelper; | ||
4 | + | ||
3 | import org.onlab.onos.net.PortNumber; | 5 | import org.onlab.onos.net.PortNumber; |
4 | import org.onlab.onos.net.flow.criteria.Criterion.Type; | 6 | import org.onlab.onos.net.flow.criteria.Criterion.Type; |
5 | import org.onlab.packet.IpPrefix; | 7 | import org.onlab.packet.IpPrefix; |
... | @@ -129,6 +131,12 @@ public final class Criteria { | ... | @@ -129,6 +131,12 @@ public final class Criteria { |
129 | public PortNumber port() { | 131 | public PortNumber port() { |
130 | return this.port; | 132 | return this.port; |
131 | } | 133 | } |
134 | + | ||
135 | + @Override | ||
136 | + public String toString() { | ||
137 | + return toStringHelper(type().toString()) | ||
138 | + .add("port", port).toString(); | ||
139 | + } | ||
132 | } | 140 | } |
133 | 141 | ||
134 | 142 | ||
... | @@ -149,6 +157,13 @@ public final class Criteria { | ... | @@ -149,6 +157,13 @@ public final class Criteria { |
149 | public MacAddress mac() { | 157 | public MacAddress mac() { |
150 | return this.mac; | 158 | return this.mac; |
151 | } | 159 | } |
160 | + | ||
161 | + @Override | ||
162 | + public String toString() { | ||
163 | + return toStringHelper(type().toString()) | ||
164 | + .add("mac", mac).toString(); | ||
165 | + } | ||
166 | + | ||
152 | } | 167 | } |
153 | 168 | ||
154 | public static final class EthTypeCriterion implements Criterion { | 169 | public static final class EthTypeCriterion implements Criterion { |
... | @@ -168,6 +183,12 @@ public final class Criteria { | ... | @@ -168,6 +183,12 @@ public final class Criteria { |
168 | return ethType; | 183 | return ethType; |
169 | } | 184 | } |
170 | 185 | ||
186 | + @Override | ||
187 | + public String toString() { | ||
188 | + return toStringHelper(type().toString()) | ||
189 | + .add("ethType", Long.toHexString(ethType)).toString(); | ||
190 | + } | ||
191 | + | ||
171 | } | 192 | } |
172 | 193 | ||
173 | 194 | ||
... | @@ -190,6 +211,11 @@ public final class Criteria { | ... | @@ -190,6 +211,11 @@ public final class Criteria { |
190 | return this.ip; | 211 | return this.ip; |
191 | } | 212 | } |
192 | 213 | ||
214 | + @Override | ||
215 | + public String toString() { | ||
216 | + return toStringHelper(type().toString()) | ||
217 | + .add("ip", ip).toString(); | ||
218 | + } | ||
193 | 219 | ||
194 | } | 220 | } |
195 | 221 | ||
... | @@ -211,6 +237,12 @@ public final class Criteria { | ... | @@ -211,6 +237,12 @@ public final class Criteria { |
211 | return proto; | 237 | return proto; |
212 | } | 238 | } |
213 | 239 | ||
240 | + @Override | ||
241 | + public String toString() { | ||
242 | + return toStringHelper(type().toString()) | ||
243 | + .add("protocol", Long.toHexString(proto)).toString(); | ||
244 | + } | ||
245 | + | ||
214 | } | 246 | } |
215 | 247 | ||
216 | 248 | ||
... | @@ -231,6 +263,12 @@ public final class Criteria { | ... | @@ -231,6 +263,12 @@ public final class Criteria { |
231 | return vlanPcp; | 263 | return vlanPcp; |
232 | } | 264 | } |
233 | 265 | ||
266 | + @Override | ||
267 | + public String toString() { | ||
268 | + return toStringHelper(type().toString()) | ||
269 | + .add("pcp", Long.toHexString(vlanPcp)).toString(); | ||
270 | + } | ||
271 | + | ||
234 | } | 272 | } |
235 | 273 | ||
236 | 274 | ||
... | @@ -252,6 +290,12 @@ public final class Criteria { | ... | @@ -252,6 +290,12 @@ public final class Criteria { |
252 | return vlanId; | 290 | return vlanId; |
253 | } | 291 | } |
254 | 292 | ||
293 | + @Override | ||
294 | + public String toString() { | ||
295 | + return toStringHelper(type().toString()) | ||
296 | + .add("id", vlanId).toString(); | ||
297 | + } | ||
298 | + | ||
255 | } | 299 | } |
256 | 300 | ||
257 | 301 | ... | ... |
1 | package org.onlab.onos.net.flow.instructions; | 1 | package org.onlab.onos.net.flow.instructions; |
2 | 2 | ||
3 | +import static com.google.common.base.MoreObjects.toStringHelper; | ||
3 | import static com.google.common.base.Preconditions.checkNotNull; | 4 | import static com.google.common.base.Preconditions.checkNotNull; |
4 | 5 | ||
5 | import org.onlab.onos.net.PortNumber; | 6 | import org.onlab.onos.net.PortNumber; |
... | @@ -47,7 +48,7 @@ public final class Instructions { | ... | @@ -47,7 +48,7 @@ public final class Instructions { |
47 | */ | 48 | */ |
48 | public static L2ModificationInstruction modL2Src(MacAddress addr) { | 49 | public static L2ModificationInstruction modL2Src(MacAddress addr) { |
49 | checkNotNull(addr, "Src l2 address cannot be null"); | 50 | checkNotNull(addr, "Src l2 address cannot be null"); |
50 | - return new ModEtherInstruction(L2SubType.L2_SRC, addr); | 51 | + return new ModEtherInstruction(L2SubType.ETH_SRC, addr); |
51 | } | 52 | } |
52 | 53 | ||
53 | /** | 54 | /** |
... | @@ -57,7 +58,7 @@ public final class Instructions { | ... | @@ -57,7 +58,7 @@ public final class Instructions { |
57 | */ | 58 | */ |
58 | public static L2ModificationInstruction modL2Dst(MacAddress addr) { | 59 | public static L2ModificationInstruction modL2Dst(MacAddress addr) { |
59 | checkNotNull(addr, "Dst l2 address cannot be null"); | 60 | checkNotNull(addr, "Dst l2 address cannot be null"); |
60 | - return new L2ModificationInstruction.ModEtherInstruction(L2SubType.L2_DST, addr); | 61 | + return new L2ModificationInstruction.ModEtherInstruction(L2SubType.ETH_DST, addr); |
61 | } | 62 | } |
62 | 63 | ||
63 | /** | 64 | /** |
... | @@ -87,7 +88,7 @@ public final class Instructions { | ... | @@ -87,7 +88,7 @@ public final class Instructions { |
87 | */ | 88 | */ |
88 | public static L3ModificationInstruction modL3Src(IpPrefix addr) { | 89 | public static L3ModificationInstruction modL3Src(IpPrefix addr) { |
89 | checkNotNull(addr, "Src l3 address cannot be null"); | 90 | checkNotNull(addr, "Src l3 address cannot be null"); |
90 | - return new ModIPInstruction(L3SubType.L3_SRC, addr); | 91 | + return new ModIPInstruction(L3SubType.IP_SRC, addr); |
91 | } | 92 | } |
92 | 93 | ||
93 | /** | 94 | /** |
... | @@ -97,7 +98,7 @@ public final class Instructions { | ... | @@ -97,7 +98,7 @@ public final class Instructions { |
97 | */ | 98 | */ |
98 | public static L3ModificationInstruction modL3Dst(IpPrefix addr) { | 99 | public static L3ModificationInstruction modL3Dst(IpPrefix addr) { |
99 | checkNotNull(addr, "Dst l3 address cannot be null"); | 100 | checkNotNull(addr, "Dst l3 address cannot be null"); |
100 | - return new ModIPInstruction(L3SubType.L3_DST, addr); | 101 | + return new ModIPInstruction(L3SubType.IP_DST, addr); |
101 | } | 102 | } |
102 | 103 | ||
103 | 104 | ||
... | @@ -110,6 +111,12 @@ public final class Instructions { | ... | @@ -110,6 +111,12 @@ public final class Instructions { |
110 | public Type type() { | 111 | public Type type() { |
111 | return Type.DROP; | 112 | return Type.DROP; |
112 | } | 113 | } |
114 | + | ||
115 | + @Override | ||
116 | + public String toString() { | ||
117 | + return toStringHelper(type()).toString(); | ||
118 | + | ||
119 | + } | ||
113 | } | 120 | } |
114 | 121 | ||
115 | 122 | ||
... | @@ -128,6 +135,11 @@ public final class Instructions { | ... | @@ -128,6 +135,11 @@ public final class Instructions { |
128 | public Type type() { | 135 | public Type type() { |
129 | return Type.OUTPUT; | 136 | return Type.OUTPUT; |
130 | } | 137 | } |
138 | + @Override | ||
139 | + public String toString() { | ||
140 | + return toStringHelper(type().toString()) | ||
141 | + .add("port", port).toString(); | ||
142 | + } | ||
131 | } | 143 | } |
132 | 144 | ||
133 | } | 145 | } | ... | ... |
1 | package org.onlab.onos.net.flow.instructions; | 1 | package org.onlab.onos.net.flow.instructions; |
2 | 2 | ||
3 | +import static com.google.common.base.MoreObjects.toStringHelper; | ||
4 | + | ||
3 | import org.onlab.packet.MacAddress; | 5 | import org.onlab.packet.MacAddress; |
4 | import org.onlab.packet.VlanId; | 6 | import org.onlab.packet.VlanId; |
5 | 7 | ||
... | @@ -15,12 +17,12 @@ public abstract class L2ModificationInstruction implements Instruction { | ... | @@ -15,12 +17,12 @@ public abstract class L2ModificationInstruction implements Instruction { |
15 | /** | 17 | /** |
16 | * Ether src modification. | 18 | * Ether src modification. |
17 | */ | 19 | */ |
18 | - L2_SRC, | 20 | + ETH_SRC, |
19 | 21 | ||
20 | /** | 22 | /** |
21 | * Ether dst modification. | 23 | * Ether dst modification. |
22 | */ | 24 | */ |
23 | - L2_DST, | 25 | + ETH_DST, |
24 | 26 | ||
25 | /** | 27 | /** |
26 | * VLAN id modification. | 28 | * VLAN id modification. |
... | @@ -66,6 +68,13 @@ public abstract class L2ModificationInstruction implements Instruction { | ... | @@ -66,6 +68,13 @@ public abstract class L2ModificationInstruction implements Instruction { |
66 | return this.mac; | 68 | return this.mac; |
67 | } | 69 | } |
68 | 70 | ||
71 | + @Override | ||
72 | + public String toString() { | ||
73 | + return toStringHelper(subtype().toString()) | ||
74 | + .add("mac", mac).toString(); | ||
75 | + } | ||
76 | + | ||
77 | + | ||
69 | } | 78 | } |
70 | 79 | ||
71 | /** | 80 | /** |
... | @@ -88,6 +97,12 @@ public abstract class L2ModificationInstruction implements Instruction { | ... | @@ -88,6 +97,12 @@ public abstract class L2ModificationInstruction implements Instruction { |
88 | return this.vlanId; | 97 | return this.vlanId; |
89 | } | 98 | } |
90 | 99 | ||
100 | + @Override | ||
101 | + public String toString() { | ||
102 | + return toStringHelper(subtype().toString()) | ||
103 | + .add("id", vlanId).toString(); | ||
104 | + } | ||
105 | + | ||
91 | } | 106 | } |
92 | 107 | ||
93 | /** | 108 | /** |
... | @@ -110,6 +125,12 @@ public abstract class L2ModificationInstruction implements Instruction { | ... | @@ -110,6 +125,12 @@ public abstract class L2ModificationInstruction implements Instruction { |
110 | return this.vlanPcp; | 125 | return this.vlanPcp; |
111 | } | 126 | } |
112 | 127 | ||
128 | + @Override | ||
129 | + public String toString() { | ||
130 | + return toStringHelper(subtype().toString()) | ||
131 | + .add("pcp", Long.toHexString(vlanPcp)).toString(); | ||
132 | + } | ||
133 | + | ||
113 | } | 134 | } |
114 | 135 | ||
115 | 136 | ... | ... |
1 | package org.onlab.onos.net.flow.instructions; | 1 | package org.onlab.onos.net.flow.instructions; |
2 | 2 | ||
3 | +import static com.google.common.base.MoreObjects.toStringHelper; | ||
4 | + | ||
3 | import org.onlab.packet.IpPrefix; | 5 | import org.onlab.packet.IpPrefix; |
4 | 6 | ||
5 | /** | 7 | /** |
... | @@ -14,12 +16,12 @@ public abstract class L3ModificationInstruction implements Instruction { | ... | @@ -14,12 +16,12 @@ public abstract class L3ModificationInstruction implements Instruction { |
14 | /** | 16 | /** |
15 | * Ether src modification. | 17 | * Ether src modification. |
16 | */ | 18 | */ |
17 | - L3_SRC, | 19 | + IP_SRC, |
18 | 20 | ||
19 | /** | 21 | /** |
20 | * Ether dst modification. | 22 | * Ether dst modification. |
21 | */ | 23 | */ |
22 | - L3_DST | 24 | + IP_DST |
23 | 25 | ||
24 | //TODO: remaining types | 26 | //TODO: remaining types |
25 | } | 27 | } |
... | @@ -58,5 +60,11 @@ public abstract class L3ModificationInstruction implements Instruction { | ... | @@ -58,5 +60,11 @@ public abstract class L3ModificationInstruction implements Instruction { |
58 | return this.ip; | 60 | return this.ip; |
59 | } | 61 | } |
60 | 62 | ||
63 | + @Override | ||
64 | + public String toString() { | ||
65 | + return toStringHelper(subtype().toString()) | ||
66 | + .add("ip", ip).toString(); | ||
67 | + } | ||
68 | + | ||
61 | } | 69 | } |
62 | } | 70 | } | ... | ... |
... | @@ -133,10 +133,10 @@ public class FlowModBuilder { | ... | @@ -133,10 +133,10 @@ public class FlowModBuilder { |
133 | L3ModificationInstruction l3m = (L3ModificationInstruction) i; | 133 | L3ModificationInstruction l3m = (L3ModificationInstruction) i; |
134 | ModIPInstruction ip; | 134 | ModIPInstruction ip; |
135 | switch (l3m.subtype()) { | 135 | switch (l3m.subtype()) { |
136 | - case L3_DST: | 136 | + case IP_DST: |
137 | ip = (ModIPInstruction) i; | 137 | ip = (ModIPInstruction) i; |
138 | return factory.actions().setNwDst(IPv4Address.of(ip.ip().toInt())); | 138 | return factory.actions().setNwDst(IPv4Address.of(ip.ip().toInt())); |
139 | - case L3_SRC: | 139 | + case IP_SRC: |
140 | ip = (ModIPInstruction) i; | 140 | ip = (ModIPInstruction) i; |
141 | return factory.actions().setNwSrc(IPv4Address.of(ip.ip().toInt())); | 141 | return factory.actions().setNwSrc(IPv4Address.of(ip.ip().toInt())); |
142 | default: | 142 | default: |
... | @@ -150,10 +150,10 @@ public class FlowModBuilder { | ... | @@ -150,10 +150,10 @@ public class FlowModBuilder { |
150 | L2ModificationInstruction l2m = (L2ModificationInstruction) i; | 150 | L2ModificationInstruction l2m = (L2ModificationInstruction) i; |
151 | ModEtherInstruction eth; | 151 | ModEtherInstruction eth; |
152 | switch (l2m.subtype()) { | 152 | switch (l2m.subtype()) { |
153 | - case L2_DST: | 153 | + case ETH_DST: |
154 | eth = (ModEtherInstruction) l2m; | 154 | eth = (ModEtherInstruction) l2m; |
155 | return factory.actions().setDlDst(MacAddress.of(eth.mac().toLong())); | 155 | return factory.actions().setDlDst(MacAddress.of(eth.mac().toLong())); |
156 | - case L2_SRC: | 156 | + case ETH_SRC: |
157 | eth = (ModEtherInstruction) l2m; | 157 | eth = (ModEtherInstruction) l2m; |
158 | return factory.actions().setDlSrc(MacAddress.of(eth.mac().toLong())); | 158 | return factory.actions().setDlSrc(MacAddress.of(eth.mac().toLong())); |
159 | case VLAN_ID: | 159 | case VLAN_ID: | ... | ... |
-
Please register or login to post a comment