blob: 29b862139ace81a5fab15bedcc10dd33bdca6335 [file] [log] [blame]
Andrea Campanella01e886e2017-12-15 15:27:31 +01001/*
Andrea Campanellaaf34b7c2018-02-08 17:10:11 +01002 * Copyright 2018-present Open Networking Foundation
Andrea Campanella01e886e2017-12-15 15:27:31 +01003 *
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.t3.cli;
18
Andrea Campanella6f2d6742018-02-07 12:00:12 +010019import com.google.common.base.Preconditions;
Ray Milkey86ad7bb2018-09-27 12:32:28 -070020import org.apache.karaf.shell.api.action.Command;
21import org.apache.karaf.shell.api.action.Option;
Andrea Campanella01e886e2017-12-15 15:27:31 +010022import org.onlab.packet.IpAddress;
23import org.onlab.packet.MacAddress;
Andrea Campanella09ca07a2018-01-25 16:44:04 +010024import org.onlab.packet.MplsLabel;
Andrea Campanella01e886e2017-12-15 15:27:31 +010025import org.onlab.packet.TpPort;
26import org.onlab.packet.VlanId;
27import org.onosproject.cli.AbstractShellCommand;
28import org.onosproject.net.ConnectPoint;
Andrea Campanella6f2d6742018-02-07 12:00:12 +010029import org.onosproject.net.DeviceId;
30import org.onosproject.net.PortNumber;
Andrea Campanella01e886e2017-12-15 15:27:31 +010031import org.onosproject.net.flow.DefaultTrafficSelector;
32import org.onosproject.net.flow.TrafficSelector;
Andrea Campanella01e886e2017-12-15 15:27:31 +010033import org.onosproject.t3.api.StaticPacketTrace;
34import org.onosproject.t3.api.TroubleshootService;
35
Andrea Campanella8be1af92018-01-24 15:14:03 +010036import static org.onlab.packet.EthType.EtherType;
37
Andrea Campanella01e886e2017-12-15 15:27:31 +010038/**
39 * Starts a Static Packet Trace for a given input and prints the result.
40 */
Andrea Campanella36769e22018-02-26 11:03:48 +010041@Command(scope = "onos", name = "t3-troubleshoot",
Andrea Campanella01e886e2017-12-15 15:27:31 +010042 description = "troubleshoots flows and groups between source and destination")
43public class TroubleshootTraceCommand extends AbstractShellCommand {
44
45
46 private static final String FLOW_SHORT_FORMAT = " %s, bytes=%s, packets=%s, "
47 + "table=%s, priority=%s, selector=%s, treatment=%s";
48
49 private static final String GROUP_FORMAT =
50 " id=0x%s, state=%s, type=%s, bytes=%s, packets=%s, appId=%s, referenceCount=%s";
51 private static final String GROUP_BUCKET_FORMAT =
52 " id=0x%s, bucket=%s, bytes=%s, packets=%s, actions=%s";
53
Andrea Campanella6f2d6742018-02-07 12:00:12 +010054 private static final String CONTROLLER = "CONTROLLER";
55
Andrea Campanella01e886e2017-12-15 15:27:31 +010056 @Option(name = "-v", aliases = "--verbose", description = "Outputs complete path")
57 private boolean verbosity1 = false;
58
59 @Option(name = "-vv", aliases = "--veryverbose", description = "Outputs flows and groups for every device")
60 private boolean verbosity2 = false;
61
62 @Option(name = "-s", aliases = "--srcIp", description = "Source IP")
63 String srcIp = null;
64
65 @Option(name = "-sp", aliases = "--srcPort", description = "Source Port", required = true)
66 String srcPort = null;
67
68 @Option(name = "-sm", aliases = "--srcMac", description = "Source MAC")
69 String srcMac = null;
70
71 @Option(name = "-et", aliases = "--ethType", description = "ETH Type", valueToShowInHelp = "ipv4")
72 String ethType = "ipv4";
73
74 @Option(name = "-stp", aliases = "--srcTcpPort", description = "Source TCP Port")
75 String srcTcpPort = null;
76
Andrea Campanella8be1af92018-01-24 15:14:03 +010077 @Option(name = "-d", aliases = "--dstIp", description = "Destination IP")
78 String dstIp = null;
Andrea Campanella01e886e2017-12-15 15:27:31 +010079
80 @Option(name = "-dm", aliases = "--dstMac", description = "Destination MAC")
81 String dstMac = null;
82
Andrea Campanella6f2d6742018-02-07 12:00:12 +010083 @Option(name = "-dtp", aliases = "--dstTcpPort", description = "destination TCP Port")
Andrea Campanella01e886e2017-12-15 15:27:31 +010084 String dstTcpPort = null;
85
86 @Option(name = "-vid", aliases = "--vlanId", description = "Vlan of incoming packet", valueToShowInHelp = "None")
87 String vlan = "None";
88
Andrea Campanella09ca07a2018-01-25 16:44:04 +010089 @Option(name = "-ml", aliases = "--mplsLabel", description = "Mpls label of incoming packet")
90 String mplsLabel = null;
91
Andrea Campanellad5bb2ef2018-01-31 16:43:23 +010092 @Option(name = "-mb", aliases = "--mplsBos", description = "MPLS BOS")
Andrea Campanella09ca07a2018-01-25 16:44:04 +010093 String mplsBos = null;
Andrea Campanella01e886e2017-12-15 15:27:31 +010094
Andrea Campanellad5bb2ef2018-01-31 16:43:23 +010095 @Option(name = "-ipp", aliases = "--ipProto", description = "IP Proto")
96 String ipProto = null;
97
98 @Option(name = "-udps", aliases = "--udpSrc", description = "UDP Source")
99 String udpSrc = null;
100
101 @Option(name = "-udpd", aliases = "--udpDst", description = "UDP Destination")
102 String udpDst = null;
103
Andrea Campanella01e886e2017-12-15 15:27:31 +0100104 @Override
Ray Milkey86ad7bb2018-09-27 12:32:28 -0700105 protected void doExecute() {
Andrea Campanella01e886e2017-12-15 15:27:31 +0100106 TroubleshootService service = get(TroubleshootService.class);
Andrea Campanella6f2d6742018-02-07 12:00:12 +0100107 String[] cpInfo = srcPort.split("/");
108 Preconditions.checkArgument(cpInfo.length == 2, "wrong format of source port");
109 ConnectPoint cp;
110 //Uses input port as a convenience to carry the Controller port, proper flood behaviour is handled in the
111 // troubleshoot manager.
112 if (cpInfo[1].equalsIgnoreCase(CONTROLLER)) {
113 cp = new ConnectPoint(DeviceId.deviceId(cpInfo[0]), PortNumber.CONTROLLER);
114 } else {
115 cp = ConnectPoint.deviceConnectPoint(srcPort);
116 }
117
Andrea Campanella8be1af92018-01-24 15:14:03 +0100118 EtherType type = EtherType.valueOf(ethType.toUpperCase());
Andrea Campanella01e886e2017-12-15 15:27:31 +0100119
120 //Input Port must be specified
121 TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder()
122 .matchInPort(cp.port());
123
124 if (srcIp != null) {
Andrea Campanella8be1af92018-01-24 15:14:03 +0100125 if (type.equals(EtherType.IPV6)) {
126 selectorBuilder.matchIPv6Src(IpAddress.valueOf(srcIp).toIpPrefix());
127 } else {
128 selectorBuilder.matchIPSrc(IpAddress.valueOf(srcIp).toIpPrefix());
129 }
Andrea Campanella01e886e2017-12-15 15:27:31 +0100130 }
131
132 if (srcMac != null) {
133 selectorBuilder.matchEthSrc(MacAddress.valueOf(srcMac));
134 }
135
136 //if EthType option is not specified using IPv4
Andrea Campanella8be1af92018-01-24 15:14:03 +0100137 selectorBuilder.matchEthType(type.ethType().toShort());
Andrea Campanella01e886e2017-12-15 15:27:31 +0100138
139 if (srcTcpPort != null) {
140 selectorBuilder.matchTcpSrc(TpPort.tpPort(Integer.parseInt(srcTcpPort)));
141 }
142
Andrea Campanella8be1af92018-01-24 15:14:03 +0100143 if (dstIp != null) {
144 if (type.equals(EtherType.IPV6)) {
145 selectorBuilder.matchIPv6Dst(IpAddress.valueOf(dstIp).toIpPrefix());
146 } else {
147 selectorBuilder.matchIPDst(IpAddress.valueOf(dstIp).toIpPrefix());
148 }
149 }
Andrea Campanella01e886e2017-12-15 15:27:31 +0100150
151 if (dstMac != null) {
152 selectorBuilder.matchEthDst(MacAddress.valueOf(dstMac));
153 }
154 if (dstTcpPort != null) {
155 selectorBuilder.matchTcpDst(TpPort.tpPort(Integer.parseInt(dstTcpPort)));
156 }
157
158 //if vlan option is not specified using NONE
159 selectorBuilder.matchVlanId(VlanId.vlanId(vlan));
160
Andrea Campanella09ca07a2018-01-25 16:44:04 +0100161 if (mplsLabel != null) {
162 selectorBuilder.matchMplsLabel(MplsLabel.mplsLabel(Integer.parseInt(mplsLabel)));
163 }
164
165 if (mplsBos != null) {
166 selectorBuilder.matchMplsBos(Boolean.valueOf(mplsBos));
167 }
Andrea Campanella01e886e2017-12-15 15:27:31 +0100168
Andrea Campanellad5bb2ef2018-01-31 16:43:23 +0100169 if (ipProto != null) {
170 selectorBuilder.matchIPProtocol(Byte.valueOf(ipProto));
171 }
172
173 if (udpSrc != null) {
174 selectorBuilder.matchUdpSrc(TpPort.tpPort(Integer.parseInt(udpSrc)));
175 }
176
177 if (udpDst != null) {
178 selectorBuilder.matchUdpDst(TpPort.tpPort(Integer.parseInt(udpDst)));
179 }
180
181
Andrea Campanella01e886e2017-12-15 15:27:31 +0100182 TrafficSelector packet = selectorBuilder.build();
183
184 //Printing the created packet
185 print("Tracing packet: %s", packet.criteria());
186
187 //Build the trace
188 StaticPacketTrace trace = service.trace(packet, cp);
Andrea Campanella01e886e2017-12-15 15:27:31 +0100189
Andrea Campanellaaf34b7c2018-02-08 17:10:11 +0100190 print("%s", T3CliUtils.printTrace(trace, verbosity1, verbosity2));
Andrea Campanella01e886e2017-12-15 15:27:31 +0100191
Andrea Campanella01e886e2017-12-15 15:27:31 +0100192 }
193}