blob: 92f78edeb29a4d2477003b17099ef0127bce6c5f [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;
pierventre4fd3b462020-10-15 17:31:44 +020029import java.util.Collection;
Andrea Campanellae4084402017-12-15 15:27:31 +010030import java.util.HashMap;
31import java.util.List;
32import java.util.Map;
Andrea Campanella6a614fa2018-02-21 14:28:20 +010033import java.util.Optional;
pierventre4fd3b462020-10-15 17:31:44 +020034import java.util.stream.Collectors;
Andrea Campanellae4084402017-12-15 15:27:31 +010035
Simon Hunt026a2872017-11-13 17:09:43 -080036/**
37 * Encapsulates the result of tracing a packet (traffic selector) through
38 * the current topology.
39 */
40public class StaticPacketTrace {
41
pierventrefe57fda2020-08-04 22:52:02 +020042 private final TrafficSelector ingressPacket;
43 private final ConnectPoint ingressPoint;
Andrea Campanellae4084402017-12-15 15:27:31 +010044 List<List<ConnectPoint>> completePaths;
45 private Map<DeviceId, List<GroupsInDevice>> outputsForDevice;
pierventrefe57fda2020-08-04 22:52:02 +020046 private Map<DeviceId, List<PipelineTraceableHitChain>> hitChainsForDevice;
Andrea Campanellae4084402017-12-15 15:27:31 +010047 private Map<DeviceId, List<FlowEntry>> flowsForDevice;
48 private StringBuilder resultMessage;
Andrea Campanella6a614fa2018-02-21 14:28:20 +010049 private Pair<Host, Host> hosts;
Andrea Campanella5af2d2b2018-03-12 19:25:44 -070050 private List<Boolean> success = new ArrayList<>();
Andrea Campanellae4084402017-12-15 15:27:31 +010051
52 /**
53 * Builds the trace with a given packet and a connect point.
54 *
pierventrefe57fda2020-08-04 22:52:02 +020055 * @param inPacket the packet to trace
56 * @param inPoint the initial connect point
Andrea Campanellae4084402017-12-15 15:27:31 +010057 */
pierventrefe57fda2020-08-04 22:52:02 +020058 public StaticPacketTrace(TrafficSelector inPacket, ConnectPoint inPoint) {
59 this.ingressPacket = inPacket;
60 this.ingressPoint = inPoint;
Andrea Campanellae4084402017-12-15 15:27:31 +010061 completePaths = new ArrayList<>();
62 outputsForDevice = new HashMap<>();
63 flowsForDevice = new HashMap<>();
pierventrefe57fda2020-08-04 22:52:02 +020064 hitChainsForDevice = new HashMap<>();
Andrea Campanellae4084402017-12-15 15:27:31 +010065 resultMessage = new StringBuilder();
Andrea Campanella6a614fa2018-02-21 14:28:20 +010066 hosts = null;
67 }
68
69 /**
70 * Builds the trace with a given packet and a connect point.
71 *
pierventrefe57fda2020-08-04 22:52:02 +020072 * @param inPacket the packet to trace
73 * @param inPoint the initial connect point
74 * @param hosts pair of source and destination hosts
Andrea Campanella6a614fa2018-02-21 14:28:20 +010075 */
pierventrefe57fda2020-08-04 22:52:02 +020076 public StaticPacketTrace(TrafficSelector inPacket, ConnectPoint inPoint, Pair<Host, Host> hosts) {
77 this.ingressPacket = inPacket;
78 this.ingressPoint = inPoint;
Andrea Campanella6a614fa2018-02-21 14:28:20 +010079 completePaths = new ArrayList<>();
80 outputsForDevice = new HashMap<>();
81 flowsForDevice = new HashMap<>();
pierventrefe57fda2020-08-04 22:52:02 +020082 hitChainsForDevice = new HashMap<>();
Andrea Campanella6a614fa2018-02-21 14:28:20 +010083 resultMessage = new StringBuilder();
84 this.hosts = hosts;
Andrea Campanellae4084402017-12-15 15:27:31 +010085 }
86
87 /**
88 * Return the initial packet.
89 *
90 * @return the initial packet in the form of a selector.
91 */
92 public TrafficSelector getInitialPacket() {
pierventrefe57fda2020-08-04 22:52:02 +020093 return ingressPacket;
Andrea Campanellae4084402017-12-15 15:27:31 +010094 }
95
96 /**
97 * Returns the first connect point the packet came in through.
98 *
99 * @return the connect point
100 */
101 public ConnectPoint getInitialConnectPoint() {
pierventrefe57fda2020-08-04 22:52:02 +0200102 return ingressPoint;
Andrea Campanellae4084402017-12-15 15:27:31 +0100103 }
104
105 /**
106 * Add a result message for the Trace.
107 *
108 * @param resultMessage the message
109 */
110 public void addResultMessage(String resultMessage) {
111 if (this.resultMessage.length() != 0) {
112 this.resultMessage.append("\n");
113 }
114 this.resultMessage.append(resultMessage);
115 }
116
117 /**
118 * Return the result message.
119 *
120 * @return the message
121 */
122 public String resultMessage() {
123 return resultMessage.toString();
124 }
125
126 /**
127 * Adds the groups for a given device.
128 *
129 * @param deviceId the device
130 * @param outputPath the groups in device objects
pierventrefe57fda2020-08-04 22:52:02 +0200131 * @deprecated in t3-4.0
Andrea Campanellae4084402017-12-15 15:27:31 +0100132 */
pierventrefe57fda2020-08-04 22:52:02 +0200133 @Deprecated
Andrea Campanellae4084402017-12-15 15:27:31 +0100134 public void addGroupOutputPath(DeviceId deviceId, GroupsInDevice outputPath) {
135 if (!outputsForDevice.containsKey(deviceId)) {
136 outputsForDevice.put(deviceId, new ArrayList<>());
137 }
138 outputsForDevice.get(deviceId).add(outputPath);
139 }
140
141 /**
pierventrefe57fda2020-08-04 22:52:02 +0200142 * Adds the pipeline hit chain for a given device.
143 *
144 * @param deviceId the device
145 * @param hitChain the hit chain
146 */
147 public void addHitChain(DeviceId deviceId, PipelineTraceableHitChain hitChain) {
148 hitChainsForDevice.compute(deviceId, (k, v) -> {
149 if (v == null) {
150 v = new ArrayList<>();
151 }
152 if (!v.contains(hitChain)) {
153 v.add(hitChain);
154 }
155 return v;
156 });
157 }
158
159 /**
Andrea Campanellae4084402017-12-15 15:27:31 +0100160 * Returns all the possible group-based outputs for a given device.
161 *
162 * @param deviceId the device
163 * @return the list of Groups for this device.
pierventrefe57fda2020-08-04 22:52:02 +0200164 * @deprecated in t3-4.0
Andrea Campanellae4084402017-12-15 15:27:31 +0100165 */
pierventrefe57fda2020-08-04 22:52:02 +0200166 @Deprecated
Andrea Campanellae4084402017-12-15 15:27:31 +0100167 public List<GroupsInDevice> getGroupOuputs(DeviceId deviceId) {
Andrea Campanella7fa8f0a2018-03-09 15:30:22 -0800168 return outputsForDevice.get(deviceId) == null ? null : ImmutableList.copyOf(outputsForDevice.get(deviceId));
Andrea Campanellae4084402017-12-15 15:27:31 +0100169 }
170
171 /**
pierventrefe57fda2020-08-04 22:52:02 +0200172 * Returns all the possible pipeline hit chains for a given device.
173 *
174 * @param deviceId the device
175 * @return the list of hit chains
176 */
177 public List<PipelineTraceableHitChain> getHitChains(DeviceId deviceId) {
178 List<PipelineTraceableHitChain> hitChains = hitChainsForDevice.get(deviceId);
179 return hitChains == null ? null : ImmutableList.copyOf(hitChains);
pierventre4fd3b462020-10-15 17:31:44 +0200180 }
pierventrefe57fda2020-08-04 22:52:02 +0200181
pierventre4fd3b462020-10-15 17:31:44 +0200182 /**
183 * Return all the dropped hit chains.
184 *
185 * @return the dropped hit chains
186 */
187 public List<PipelineTraceableHitChain> getDroppedHitChains() {
188 return hitChainsForDevice.values().stream()
189 .flatMap(Collection::stream)
190 .filter(PipelineTraceableHitChain::isDropped)
191 .collect(Collectors.toList());
pierventrefe57fda2020-08-04 22:52:02 +0200192 }
193
194 /**
Andrea Campanellae4084402017-12-15 15:27:31 +0100195 * Adds a complete possible path.
196 *
197 * @param completePath the path
198 */
199 public void addCompletePath(List<ConnectPoint> completePath) {
200 completePaths.add(completePath);
201 }
202
203 /**
204 * Return all the possible path the packet can take through the network.
205 *
206 * @return a list of paths
207 */
208 public List<List<ConnectPoint>> getCompletePaths() {
209 return completePaths;
210 }
211
212 /**
213 * Add the flows traversed by the packet in a given device.
214 *
215 * @param deviceId the device considered
216 * @param flows the flows
pierventrefe57fda2020-08-04 22:52:02 +0200217 * @deprecated in t3-4.0
Andrea Campanellae4084402017-12-15 15:27:31 +0100218 */
pierventrefe57fda2020-08-04 22:52:02 +0200219 @Deprecated
Andrea Campanellae4084402017-12-15 15:27:31 +0100220 public void addFlowsForDevice(DeviceId deviceId, List<FlowEntry> flows) {
221 flowsForDevice.put(deviceId, flows);
222 }
223
224 /**
225 * Returns the flows matched by this trace's packet for a given device.
226 *
227 * @param deviceId the device
228 * @return the flows matched
pierventrefe57fda2020-08-04 22:52:02 +0200229 * @deprecated in t3-4.0
Andrea Campanellae4084402017-12-15 15:27:31 +0100230 */
pierventrefe57fda2020-08-04 22:52:02 +0200231 @Deprecated
Andrea Campanellae4084402017-12-15 15:27:31 +0100232 public List<FlowEntry> getFlowsForDevice(DeviceId deviceId) {
Andrea Campanella20c17052018-01-30 16:19:35 +0100233 return flowsForDevice.getOrDefault(deviceId, ImmutableList.of());
Andrea Campanellae4084402017-12-15 15:27:31 +0100234 }
235
Andrea Campanella6a614fa2018-02-21 14:28:20 +0100236 /**
237 * Return, if present, the two hosts at the endpoints of this trace.
238 *
239 * @return pair of source and destination hosts
240 */
241 public Optional<Pair<Host, Host>> getEndpointHosts() {
242 return Optional.ofNullable(hosts);
243 }
244
245 /**
246 * Sets the two hosts at the endpoints of this trace.
247 *
248 * @param endpointHosts pair of source and destination hosts
249 */
250 public void addEndpointHosts(Pair<Host, Host> endpointHosts) {
251 hosts = endpointHosts;
252 }
253
Andrea Campanella0cc6acd2018-02-28 16:43:16 +0100254 /**
Andrea Campanella5af2d2b2018-03-12 19:25:44 -0700255 * Return if all the possible paths of this trace are successful.
Andrea Campanella7fa8f0a2018-03-09 15:30:22 -0800256 *
Andrea Campanella5af2d2b2018-03-12 19:25:44 -0700257 * @return true if all paths are successful
Andrea Campanella0cc6acd2018-02-28 16:43:16 +0100258 */
259 public boolean isSuccess() {
Andrea Campanella5af2d2b2018-03-12 19:25:44 -0700260 return !success.contains(false);
Andrea Campanella0cc6acd2018-02-28 16:43:16 +0100261 }
262
263 /**
Andrea Campanella5af2d2b2018-03-12 19:25:44 -0700264 * Sets if a path from this trace is successful.
Andrea Campanella7fa8f0a2018-03-09 15:30:22 -0800265 *
Andrea Campanella5af2d2b2018-03-12 19:25:44 -0700266 * @param success true if a path of trace is successful.
Andrea Campanella0cc6acd2018-02-28 16:43:16 +0100267 */
268 public void setSuccess(boolean success) {
Andrea Campanella5af2d2b2018-03-12 19:25:44 -0700269 this.success.add(success);
Andrea Campanella0cc6acd2018-02-28 16:43:16 +0100270 }
271
Andrea Campanellae4084402017-12-15 15:27:31 +0100272 @Override
273 public String toString() {
274 return "StaticPacketTrace{" +
pierventrefe57fda2020-08-04 22:52:02 +0200275 "ingressPacket=" + ingressPacket +
276 ", ingressPoint=" + ingressPoint +
Andrea Campanellae4084402017-12-15 15:27:31 +0100277 ", completePaths=" + completePaths +
278 ", outputsForDevice=" + outputsForDevice +
279 ", flowsForDevice=" + flowsForDevice +
pierventrefe57fda2020-08-04 22:52:02 +0200280 ", hitChains=" + hitChainsForDevice +
Andrea Campanellae4084402017-12-15 15:27:31 +0100281 ", resultMessage=" + resultMessage +
282 '}';
283 }
Simon Hunt026a2872017-11-13 17:09:43 -0800284}