blob: 57e1dcef9c407d8bcdf62976ed58578864ebd83b [file] [log] [blame]
Simon Hunt026a2872017-11-13 17:09:43 -08001/*
2 * Copyright 2017-present Open Networking Foundation
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
17package org.onosproject.t3.api;
18
Andrea Campanella20c17052018-01-30 16:19:35 +010019import com.google.common.collect.ImmutableList;
Andrea Campanella6a614fa2018-02-21 14:28:20 +010020import org.apache.commons.lang3.tuple.Pair;
Andrea Campanellae4084402017-12-15 15:27:31 +010021import org.onosproject.net.ConnectPoint;
22import org.onosproject.net.DeviceId;
Andrea Campanella6a614fa2018-02-21 14:28:20 +010023import org.onosproject.net.Host;
pierventrefe57fda2020-08-04 22:52:02 +020024import org.onosproject.net.PipelineTraceableHitChain;
Andrea Campanellae4084402017-12-15 15:27:31 +010025import org.onosproject.net.flow.FlowEntry;
26import org.onosproject.net.flow.TrafficSelector;
27
28import java.util.ArrayList;
29import java.util.HashMap;
30import java.util.List;
31import java.util.Map;
Andrea Campanella6a614fa2018-02-21 14:28:20 +010032import java.util.Optional;
Andrea Campanellae4084402017-12-15 15:27:31 +010033
Simon Hunt026a2872017-11-13 17:09:43 -080034/**
35 * Encapsulates the result of tracing a packet (traffic selector) through
36 * the current topology.
37 */
38public class StaticPacketTrace {
39
pierventrefe57fda2020-08-04 22:52:02 +020040 private final TrafficSelector ingressPacket;
41 private final ConnectPoint ingressPoint;
Andrea Campanellae4084402017-12-15 15:27:31 +010042 List<List<ConnectPoint>> completePaths;
43 private Map<DeviceId, List<GroupsInDevice>> outputsForDevice;
pierventrefe57fda2020-08-04 22:52:02 +020044 private Map<DeviceId, List<PipelineTraceableHitChain>> hitChainsForDevice;
Andrea Campanellae4084402017-12-15 15:27:31 +010045 private Map<DeviceId, List<FlowEntry>> flowsForDevice;
46 private StringBuilder resultMessage;
Andrea Campanella6a614fa2018-02-21 14:28:20 +010047 private Pair<Host, Host> hosts;
Andrea Campanella5af2d2b2018-03-12 19:25:44 -070048 private List<Boolean> success = new ArrayList<>();
Andrea Campanellae4084402017-12-15 15:27:31 +010049
50 /**
51 * Builds the trace with a given packet and a connect point.
52 *
pierventrefe57fda2020-08-04 22:52:02 +020053 * @param inPacket the packet to trace
54 * @param inPoint the initial connect point
Andrea Campanellae4084402017-12-15 15:27:31 +010055 */
pierventrefe57fda2020-08-04 22:52:02 +020056 public StaticPacketTrace(TrafficSelector inPacket, ConnectPoint inPoint) {
57 this.ingressPacket = inPacket;
58 this.ingressPoint = inPoint;
Andrea Campanellae4084402017-12-15 15:27:31 +010059 completePaths = new ArrayList<>();
60 outputsForDevice = new HashMap<>();
61 flowsForDevice = new HashMap<>();
pierventrefe57fda2020-08-04 22:52:02 +020062 hitChainsForDevice = new HashMap<>();
Andrea Campanellae4084402017-12-15 15:27:31 +010063 resultMessage = new StringBuilder();
Andrea Campanella6a614fa2018-02-21 14:28:20 +010064 hosts = null;
65 }
66
67 /**
68 * Builds the trace with a given packet and a connect point.
69 *
pierventrefe57fda2020-08-04 22:52:02 +020070 * @param inPacket the packet to trace
71 * @param inPoint the initial connect point
72 * @param hosts pair of source and destination hosts
Andrea Campanella6a614fa2018-02-21 14:28:20 +010073 */
pierventrefe57fda2020-08-04 22:52:02 +020074 public StaticPacketTrace(TrafficSelector inPacket, ConnectPoint inPoint, Pair<Host, Host> hosts) {
75 this.ingressPacket = inPacket;
76 this.ingressPoint = inPoint;
Andrea Campanella6a614fa2018-02-21 14:28:20 +010077 completePaths = new ArrayList<>();
78 outputsForDevice = new HashMap<>();
79 flowsForDevice = new HashMap<>();
pierventrefe57fda2020-08-04 22:52:02 +020080 hitChainsForDevice = new HashMap<>();
Andrea Campanella6a614fa2018-02-21 14:28:20 +010081 resultMessage = new StringBuilder();
82 this.hosts = hosts;
Andrea Campanellae4084402017-12-15 15:27:31 +010083 }
84
85 /**
86 * Return the initial packet.
87 *
88 * @return the initial packet in the form of a selector.
89 */
90 public TrafficSelector getInitialPacket() {
pierventrefe57fda2020-08-04 22:52:02 +020091 return ingressPacket;
Andrea Campanellae4084402017-12-15 15:27:31 +010092 }
93
94 /**
95 * Returns the first connect point the packet came in through.
96 *
97 * @return the connect point
98 */
99 public ConnectPoint getInitialConnectPoint() {
pierventrefe57fda2020-08-04 22:52:02 +0200100 return ingressPoint;
Andrea Campanellae4084402017-12-15 15:27:31 +0100101 }
102
103 /**
104 * Add a result message for the Trace.
105 *
106 * @param resultMessage the message
107 */
108 public void addResultMessage(String resultMessage) {
109 if (this.resultMessage.length() != 0) {
110 this.resultMessage.append("\n");
111 }
112 this.resultMessage.append(resultMessage);
113 }
114
115 /**
116 * Return the result message.
117 *
118 * @return the message
119 */
120 public String resultMessage() {
121 return resultMessage.toString();
122 }
123
124 /**
125 * Adds the groups for a given device.
126 *
127 * @param deviceId the device
128 * @param outputPath the groups in device objects
pierventrefe57fda2020-08-04 22:52:02 +0200129 * @deprecated in t3-4.0
Andrea Campanellae4084402017-12-15 15:27:31 +0100130 */
pierventrefe57fda2020-08-04 22:52:02 +0200131 @Deprecated
Andrea Campanellae4084402017-12-15 15:27:31 +0100132 public void addGroupOutputPath(DeviceId deviceId, GroupsInDevice outputPath) {
133 if (!outputsForDevice.containsKey(deviceId)) {
134 outputsForDevice.put(deviceId, new ArrayList<>());
135 }
136 outputsForDevice.get(deviceId).add(outputPath);
137 }
138
139 /**
pierventrefe57fda2020-08-04 22:52:02 +0200140 * Adds the pipeline hit chain for a given device.
141 *
142 * @param deviceId the device
143 * @param hitChain the hit chain
144 */
145 public void addHitChain(DeviceId deviceId, PipelineTraceableHitChain hitChain) {
146 hitChainsForDevice.compute(deviceId, (k, v) -> {
147 if (v == null) {
148 v = new ArrayList<>();
149 }
150 if (!v.contains(hitChain)) {
151 v.add(hitChain);
152 }
153 return v;
154 });
155 }
156
157 /**
Andrea Campanellae4084402017-12-15 15:27:31 +0100158 * Returns all the possible group-based outputs for a given device.
159 *
160 * @param deviceId the device
161 * @return the list of Groups for this device.
pierventrefe57fda2020-08-04 22:52:02 +0200162 * @deprecated in t3-4.0
Andrea Campanellae4084402017-12-15 15:27:31 +0100163 */
pierventrefe57fda2020-08-04 22:52:02 +0200164 @Deprecated
Andrea Campanellae4084402017-12-15 15:27:31 +0100165 public List<GroupsInDevice> getGroupOuputs(DeviceId deviceId) {
Andrea Campanella7fa8f0a2018-03-09 15:30:22 -0800166 return outputsForDevice.get(deviceId) == null ? null : ImmutableList.copyOf(outputsForDevice.get(deviceId));
Andrea Campanellae4084402017-12-15 15:27:31 +0100167 }
168
169 /**
pierventrefe57fda2020-08-04 22:52:02 +0200170 * Returns all the possible pipeline hit chains for a given device.
171 *
172 * @param deviceId the device
173 * @return the list of hit chains
174 */
175 public List<PipelineTraceableHitChain> getHitChains(DeviceId deviceId) {
176 List<PipelineTraceableHitChain> hitChains = hitChainsForDevice.get(deviceId);
177 return hitChains == null ? null : ImmutableList.copyOf(hitChains);
178
179 }
180
181 /**
Andrea Campanellae4084402017-12-15 15:27:31 +0100182 * Adds a complete possible path.
183 *
184 * @param completePath the path
185 */
186 public void addCompletePath(List<ConnectPoint> completePath) {
187 completePaths.add(completePath);
188 }
189
190 /**
191 * Return all the possible path the packet can take through the network.
192 *
193 * @return a list of paths
194 */
195 public List<List<ConnectPoint>> getCompletePaths() {
196 return completePaths;
197 }
198
199 /**
200 * Add the flows traversed by the packet in a given device.
201 *
202 * @param deviceId the device considered
203 * @param flows the flows
pierventrefe57fda2020-08-04 22:52:02 +0200204 * @deprecated in t3-4.0
Andrea Campanellae4084402017-12-15 15:27:31 +0100205 */
pierventrefe57fda2020-08-04 22:52:02 +0200206 @Deprecated
Andrea Campanellae4084402017-12-15 15:27:31 +0100207 public void addFlowsForDevice(DeviceId deviceId, List<FlowEntry> flows) {
208 flowsForDevice.put(deviceId, flows);
209 }
210
211 /**
212 * Returns the flows matched by this trace's packet for a given device.
213 *
214 * @param deviceId the device
215 * @return the flows matched
pierventrefe57fda2020-08-04 22:52:02 +0200216 * @deprecated in t3-4.0
Andrea Campanellae4084402017-12-15 15:27:31 +0100217 */
pierventrefe57fda2020-08-04 22:52:02 +0200218 @Deprecated
Andrea Campanellae4084402017-12-15 15:27:31 +0100219 public List<FlowEntry> getFlowsForDevice(DeviceId deviceId) {
Andrea Campanella20c17052018-01-30 16:19:35 +0100220 return flowsForDevice.getOrDefault(deviceId, ImmutableList.of());
Andrea Campanellae4084402017-12-15 15:27:31 +0100221 }
222
Andrea Campanella6a614fa2018-02-21 14:28:20 +0100223 /**
224 * Return, if present, the two hosts at the endpoints of this trace.
225 *
226 * @return pair of source and destination hosts
227 */
228 public Optional<Pair<Host, Host>> getEndpointHosts() {
229 return Optional.ofNullable(hosts);
230 }
231
232 /**
233 * Sets the two hosts at the endpoints of this trace.
234 *
235 * @param endpointHosts pair of source and destination hosts
236 */
237 public void addEndpointHosts(Pair<Host, Host> endpointHosts) {
238 hosts = endpointHosts;
239 }
240
Andrea Campanella0cc6acd2018-02-28 16:43:16 +0100241 /**
Andrea Campanella5af2d2b2018-03-12 19:25:44 -0700242 * Return if all the possible paths of this trace are successful.
Andrea Campanella7fa8f0a2018-03-09 15:30:22 -0800243 *
Andrea Campanella5af2d2b2018-03-12 19:25:44 -0700244 * @return true if all paths are successful
Andrea Campanella0cc6acd2018-02-28 16:43:16 +0100245 */
246 public boolean isSuccess() {
Andrea Campanella5af2d2b2018-03-12 19:25:44 -0700247 return !success.contains(false);
Andrea Campanella0cc6acd2018-02-28 16:43:16 +0100248 }
249
250 /**
Andrea Campanella5af2d2b2018-03-12 19:25:44 -0700251 * Sets if a path from this trace is successful.
Andrea Campanella7fa8f0a2018-03-09 15:30:22 -0800252 *
Andrea Campanella5af2d2b2018-03-12 19:25:44 -0700253 * @param success true if a path of trace is successful.
Andrea Campanella0cc6acd2018-02-28 16:43:16 +0100254 */
255 public void setSuccess(boolean success) {
Andrea Campanella5af2d2b2018-03-12 19:25:44 -0700256 this.success.add(success);
Andrea Campanella0cc6acd2018-02-28 16:43:16 +0100257 }
258
Andrea Campanellae4084402017-12-15 15:27:31 +0100259 @Override
260 public String toString() {
261 return "StaticPacketTrace{" +
pierventrefe57fda2020-08-04 22:52:02 +0200262 "ingressPacket=" + ingressPacket +
263 ", ingressPoint=" + ingressPoint +
Andrea Campanellae4084402017-12-15 15:27:31 +0100264 ", completePaths=" + completePaths +
265 ", outputsForDevice=" + outputsForDevice +
266 ", flowsForDevice=" + flowsForDevice +
pierventrefe57fda2020-08-04 22:52:02 +0200267 ", hitChains=" + hitChainsForDevice +
Andrea Campanellae4084402017-12-15 15:27:31 +0100268 ", resultMessage=" + resultMessage +
269 '}';
270 }
Simon Hunt026a2872017-11-13 17:09:43 -0800271}